Common annotations for Spring

The Spring framework mainly includes IoC and AOP, both of which can be configured using annotations.

Development environment: IntelliJ IDEA 2019.2.2
Spring Boot version: 2.1.8
Create a new Spring Boot project named demo.

1. Bean definition

In Spring, it forms the backbone of the application The objects managed by the Spring IoC container are called beans.
Bean is an object that is instantiated, assembled and managed by the Spring IoC container.
Use @Component, @Service, or @Configuration annotations to decorate a class. These classes will be automatically detected by Spring and registered in the container. Using @Bean annotations to modify the methods in the class will be treated as A bean is stored in the Spring container.

The following example implements how to get the name of the bean according to the type, and get the bean;

1, create a new class MyBean.java

package com.example.demo;


public class MyBean {

public MyBean(String id){
this.id = id;
}

private String id;

public String getId() {
return id;
}

public void setId(String id) {
this.id = id;
}
}

2, create a new class MyConfig.java

package com.example.demo;


import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;

@Configuration
public class MyConfig {

//The default bean name is the method name, which is getMyBean below
@Bean
public MyBean getMyBean(){
return new MyBean("1");
}

//Set the name of the bean to bean
@Bean("bean2")
public MyBean getMyBean2(){
return new MyBean("2");
}
}

3. Modify the startup class code DemoApplication.java

package com.example.demo;


import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
import org.springframework.context.ApplicationContext;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;

@SpringBootApplication
@RestController
public class DemoApplication {

public static void main(String[] args) {
SpringApplication.run(DemoApplication.
class, args);
}

@Autowired
ApplicationContext ctx;

@RequestMapping(value
= "/")
public String index(){
//Get the bean name according to the type
String[] names = ctx.getBeanNamesForType(MyBean.class);
for(String name: names){
System.out.println(name);
}

//Get the bean
MyBean bean1 = (MyBean)ctx.getBean("getMyBean");
System.out.println(bean1.getId());

MyBean bean2
= (MyBean)ctx.getBean("bean2");
System.out.println(bean2.getId());

return "";
}
}

After running the project, the browser visits: http://localhost:8080/, IDEA console output:
getMyBean
bean2
1
2

Project structure

Share pictures

Second, dependency injection

< p>Using annotations can achieve instance injection, the most commonly used ones are @Resource and @Autowired.
@Resource is an annotation defined by JSR-250, which will be injected according to the name by default.
@Autowired will inject according to the type by default.

1, continue to use the two classes MyBean.java and MyConfig.java in the above example

2, modify the startup class code DemoApplication.java

package com.example.demo;


import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;

import javax.annotation.Resource;

@SpringBootApplication
@RestController
public class DemoApplication {

public static void main(String[] args) {
SpringApplication.run(DemoApplication.
class, args);
}

//Using @Resource injection
@Resource(name="getMyBean")
MyBean myBean1;

//Using @Autowired injection
@Autowired
MyBean bean2;

@RequestMapping(value
= "/")
public String index(){
System.out.println(myBean1.getId());
System.out.println(bean2.getId());
return "";
}
}

Browser access: http://localhost:8080/, IDEA console output:
getMyBean
bean2
1
2

Note:
The bean2 of MyBean bean2 above cannot be modified to another name. Reason:
@Autowired injects according to the type. If there is only one bean of type MyBean in the container, bean2 can be named arbitrarily.
However, there are two MyBean type beans in this example container. If there are multiple beans in this case, look up according to the attribute name, where the attribute name bean2 will eventually find the corresponding bean.
If you change MyBean bean2 to MyBean myBean2, the IEAD console will report exception information during runtime:

Field myBean2 in com.example.demo.DemoApplication required a single bean, but 2 were found:

-getMyBean: defined by method ‘getMyBean’ in class path resource [com/example/demo/MyConfig.class]
-bean2: defined by method'getMyBean2' in class path resource [com/example/demo/MyConfig.class]

The injection method of the above example is set value injection. You can use construct injection to inject beans into the controller’s constructor.
Only @Autowired annotation can be used to decorate the constructor, and @Resource cannot modify the constructor.
Example:

package com .example.demo;


import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;

import javax.annotation.Resource;

@SpringBootApplication
@RestController
public class DemoApplication {

public static void main(String[] args) {
SpringApplication.run(DemoApplication.
class, args);
}

MyBean bean2;

//Construction injection
@Autowired
public DemoApplication(MyBean bean2){
this.bean2 = bean2;
}

@RequestMapping(value
= "/")
public String index(){
System.out.println(bean2.getId());
return "";
}
}

Three, use Primary annotations

According to Type injection. If there are multiple beans of the same type in the container, an exception will be thrown because Spring does not know which bean to inject.
For this problem, you can use the @Primary annotation.

1. Modify the code of MyConfig.java, add annotation @Primary

package com.example.demo;


import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.context.annotation.Primary;

@Configuration
public class MyConfig {

//The default bean name is the method name, which is getMyBean below
@Bean
@Primary
public MyBean getMyBean(){
return new MyBean("1");
}

//Set the name of the bean to bean
@Bean("bean2")
public MyBean getMyBean2(){
return new MyBean("2");
}
}

2, start the class code DemoApplication.java or use the above example

package com.example.demo;


import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;

import javax.annotation.Resource;

@SpringBootApplication
@RestController
public class DemoApplication {

public static void main(String[] args) {
SpringApplication.run(DemoApplication.
class, args);
}

//Using @Resource injection
@Resource(name="getMyBean")
MyBean myBean1;

//Using @Autowired injection
@Autowired
MyBean bean2;

@RequestMapping(value
= "/")
public String index(){
System.out.println(myBean1.getId());
System.out.println(bean2.getId());
return "";
}
}

Browser access: http://localhost:8080/, IDEA console output:
1
1

Four. Scope annotation

When configuring the bean, you can specify the scope of the bean (scope) , The general bean can be configured as singleton or non-singleton (prototype).
When configured as singleton, Spring’s bean factory only returns instances of the same bean.
When configured as prototype, a new instance will be created each time.

1. Modify the code MyConfig.java

package com.example.demo;


import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
import org.springframework.context.ApplicationContext;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;

import javax.annotation.Resource;

@SpringBootApplication
@RestController
public class DemoApplication {

public static void main(String[] args) {
SpringApplication.run(DemoApplication.
class, args);
}

@Autowired
ApplicationContext ctx;

@RequestMapping(value
= "/")
public String index(){
String s
= "prototype:" + ctx.getBean("bean1") + "
"
+ "singleton:" + ctx.getBean("bean2") + "
";
return s;
}
}

Browser access: http://localhost:8080/, multiple refreshes, page content changes:
prototype:[emailprotected ]
singleton:[email protected]
prototype:[email protected]
……

Note:
If you inject one into a singleton bean For non-monomorphic beans, the non-monomorphic bean instances maintained by this monomorphic bean will not be refreshed.
The example Spring MVC controller is monomorphic. If you inject a non-monomorphic bean into the controller, as shown below:

 //Inject a non-monomorphic bean

@Autowired
private MyBean bean1;

@RequestMapping(value
= "/")
public String index(){
return bean1.toString();
}

Browser visit: http://localhost:8080/, multiple refreshes, the page is displayed as follows:
[emailprotected]
Explain that the MyBean output by the index() method calls the same instance, because when the controller is initialized, a bean has been injected and the same instance has been maintained.

Five, method injection

If it is in a monomorphic bean Inject a non-monomorphic bean, the non-monomorphic bean instance maintained by the monomorphic bean will not be refreshed.
There are two simple solutions:
1. On the side that needs to be injected (monomorphic bean), use ApplicationContext directly, and each time a non-monomorphic bean is called, it will be returned by the container.

package com.example.demo;


import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.context.ApplicationContext;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;

@RestController
public class DemoController {

@Autowired
private ApplicationContext ctx;

private MyBean getBean1(){
return (MyBean)ctx.getBean("bean1");/ /A non-monomorphic bean
}

@RequestMapping(value
= "/")
public String index(){
return getBean1().toString();
}
}

Browser visit: http://localhost:8080/, multiple refreshes, the page changes every time:
[emailprotected]
[email protected]
……

2, use Spring method injection.
Use the @Lookup annotation to decorate an abstract method that will return an instance of the bean.
The running result of the following code is the same as the above using ApplicationContext.

package com.example.demo;


import org.springframework.beans.factory.annotation.Lookup;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;

@RestController
public abstract class DemoController {
@Lookup(
"bean1")
public abstract MyBean createBean();

@RequestMapping(value
= "/")
public String index(){
return createBean().toString();
}
}

Six, AOP annotations

Realize AOP Features use AspectJ annotations
1. Need to add dependency in pom.xml:

 << span style="color: #800000;">dependency>

<groupId >org.aspectjgroupId>
<artifactId >aspectjweaverartifactId>
dependency>

2, create a new business class TestServiceImpl.java

package com.example.demo;


import org.springframework.stereotype.Component;

@Component
public class TestServiceImpl {
public void testService(){
System.out.println(
"Business method to be represented");
}
}

3. Create a new proxy class ProxyService.java

package com.example.demo;


import org.aspectj.lang.annotation.After;
import org.aspectj.lang.annotation.Aspect;
import org.aspectj.lang.annotation.Before;
import org.springframework.stereotype.Component;

@Aspect
@Component
public class ProxyService {
@Before(
"execution(* com.example.demo.*ServiceImpl.*(..))")
public void before(){
System.out.println(
"Execute before calling the business method");
}
@After(
"execution(* com.example.demo.*ServiceImpl.*(..))")
public void after(){
System.out.println(
"Execute after the business method is called");
}
}

4. Modify the startup class method DemoApplication.java

package com.example.demo;


import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
import org.springframework.boot.builder.SpringApplicationBuilder;

@SpringBootApplication
public abstract class DemoApplication {
public static void main(String[] args) {
//SpringApplication.run(DemoApplication.class, args);< /span>
new SpringApplicationBuilder(DemoApplication.class).properties(
"spring.aop.proxy-target-class=true"
).run(args);
}
}

5. Controller DemoController.java

package com.example.demo;


import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;

@RestController
public class DemoController {

@Autowired
TestServiceImpl testService;

@RequestMapping(value
= "/")
public String index(){
testService.testService();
System.out.println(
"TestServiceImpl's class:" + testService.getClass());
return "";
}
}

Browser access: http://localhost:8080/, output in the console:
execute before calling the business method
delegate
The business method is executed after the business method is called
Class of TestServiceImpl:class com.example.demo.TestServiceImpl$$EnhancerBySpringCGLIB$$2a53cdeb

VII. ComponentScan annotation

ComponentScan annotation is mainly used to detect components decorated with @Component, including components that indirectly use @Component (such as @Service, @ Repository, @Controller) and register them in the Spring container.

package com.example.demo;


public class MyBean {

public MyBean(String id){
this.id = id;
}

private String id;

public String getId() {
return id;
}

public void setId(String id) {
this.id = id;
}
}

package com.example.demo;


import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;

@Configuration
public class MyConfig {

//The default bean name is the method name, which is getMyBean below
@Bean
public MyBean getMyBean(){
return new MyBean("1");
}

//Set the name of the bean to bean
@Bean("bean2")
public MyBean getMyBean2(){
return new MyBean("2");
}
}

package com.example.demo;


import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
import org.springframework.context.ApplicationContext;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;

@SpringBootApplication
@RestController
public class DemoApplication {

public static void main(String[] args) {
SpringApplication.run(DemoApplication.
class, args);
}

@Autowired
ApplicationContext ctx;

@RequestMapping(value
= "/")
public String index(){
//Get the bean name according to the type
String[] names = ctx.getBeanNamesForType(MyBean.class);
for(String name: names){
System.out.println(name);
}

//Get the bean
MyBean bean1 = (MyBean)ctx.getBean("getMyBean");
System.out.println(bean1.getId());

MyBean bean2
= (MyBean)ctx.getBean("bean2");
System.out.println(bean2.getId());

return "";
}
}

package com.example.demo;


import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;

import javax.annotation.Resource;

@SpringBootApplication
@RestController
public class DemoApplication {

public static void main(String[] args) {
SpringApplication.run(DemoApplication.
class, args);
}

//Using @Resource injection
@Resource(name="getMyBean")
MyBean myBean1;

//Using @Autowired injection
@Autowired
MyBean bean2;

@RequestMapping(value
= "/")
public String index(){
System.out.println(myBean1.getId());
System.out.println(bean2.getId());
return "";
}
}

Field myBean2 in com.example.demo.DemoApplication required a single bean, but 2 were found:

-getMyBean: defined by method ‘getMyBean’ in class path resource [com/example/demo/MyConfig.class]
-bean2: defined by method'getMyBean2' in class path resource [com/example/demo/MyConfig.class]

package com.example.demo;


import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;

import javax.annotation.Resource;

@SpringBootApplication
@RestController
public class DemoApplication {

public static void main(String[] args) {
SpringApplication.run(DemoApplication.
class, args);
}

MyBean bean2;

//Construction injection
@Autowired
public DemoApplication(MyBean bean2){
this.bean2 = bean2;
}

@RequestMapping(value
= "/")
public String index(){
System.out.println(bean2.getId());
return "";
}
}

package com.example.demo;


import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.context.annotation.Primary;

@Configuration
public class MyConfig {

//默认bean的名称为方法名,即下面的getMyBean
@Bean
@Primary
public MyBean getMyBean(){
return new MyBean("1");
}

//设置bean的名称为bean
@Bean("bean2")
public MyBean getMyBean2(){
return new MyBean("2");
}
}

package com.example.demo;


import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;

import javax.annotation.Resource;

@SpringBootApplication
@RestController
public class DemoApplication {

public static void main(String[] args) {
SpringApplication.run(DemoApplication.
class, args);
}

//使用@Resource注入
@Resource(name="getMyBean")
MyBean myBean1;

//使用@Autowired注入
@Autowired
MyBean bean2;

@RequestMapping(value
= "/")
public String index(){
System.out.println(myBean1.getId());
System.out.println(bean2.getId());
return "";
}
}

package com.example.demo;


import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
import org.springframework.context.ApplicationContext;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;

import javax.annotation.Resource;

@SpringBootApplication
@RestController
public class DemoApplication {

public static void main(String[] args) {
SpringApplication.run(DemoApplication.
class, args);
}

@Autowired
ApplicationContext ctx;

@RequestMapping(value
= "/")
public String index(){
String s
= "prototype:" + ctx.getBean("bean1") + "
"
+ "singleton:" + ctx.getBean("bean2") + "
";
return s;
}
}

    //注入一个非单态的bean

@Autowired
private MyBean bean1;

@RequestMapping(value
= "/")
public String index(){
return bean1.toString();
}

package com.example.demo;


import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.context.ApplicationContext;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;

@RestController
public class DemoController {

@Autowired
private ApplicationContext ctx;

private MyBean getBean1(){
return (MyBean)ctx.getBean("bean1");//一个非单态的bean
}

@RequestMapping(value
= "/")
public String index(){
return getBean1().toString();
}
}

package com.example.demo;


import org.springframework.beans.factory.annotation.Lookup;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;

@RestController
public abstract class DemoController {
@Lookup(
"bean1")
public abstract MyBean createBean() ;

@RequestMapping(value
= "/")
public String index(){
return createBean().toString();
}
}

        <dependency>

<groupId>org.aspectjgroupId>
<artifactId>aspectjweaverartifactId>
dependency>

package com.example.demo;


import org.springframework.stereotype.Component;

@Component
public class TestServiceImpl {
public void testService(){
System.out.println(
"要代理的业务方法");
}
}

package com.example.demo;


import org.aspectj.lang.annotation.After;
import org.aspectj.lang.annotation.Aspect;
import org.aspectj.lang.annotation.Before;
import org.springframework.stereotype.Component;

@Aspect
@Component
public class ProxyService {
@Before(
"execution(* com.example.demo.*ServiceImpl.*(..))")
public void before(){
System.out.println(
"业务方法调用前执行");
}
@After(
"execution(* com.example.demo.*ServiceImpl.*(..))")
public void after(){
System.out.println(
"业务方法调用后执行");
}
}

package com.example.demo;


import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
import org.springframework.boot.builder.SpringApplicationBuilder;

@SpringBootApplication
public abstract class DemoApplication {
public static void main(String[] args) {
//SpringApplication.run(DemoApplication.class, args);
new SpringApplicationBuilder(DemoApplication.class).properties(
"spring.aop.proxy-target-class=true"
).run(args);
}
}

package com.example.demo;


import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;

@RestController
public class DemoController {

@Autowired
TestServiceImpl testService;

@RequestMapping(value
= "/")
public String index(){
testService.testService();
System.out.println(
"TestServiceImpl的class:" + testService.getClass());
return "";
}
}

Leave a Comment

Your email address will not be published.