Spring configures beans based on annotations

Introduction to the

This injection is also common and is one of the most widely used DI patterns in Spring enterprise development, and sometimes Autowire injection is convenient compared to XML configuration patterns. You need to import the AOP-enabled package first, because you need to tell the Spring container in the XML configuration file to scan for the package containing the annotations file.

classification

1) @Component can use this annotation to describe beans in Spring, but it is a generic concept that represents only a Component (Bean) and can be applied at any level. To use it, simply annotate the annotation on the corresponding class. 2) @Repository identifies classes in the data access layer (DAO layer) as beans in Spring, which does the same thing as @Component. 3) @Service is typically used at the Service layer to identify business layer classes as Beans in Spring, with the same functionality as @Component. 4) @controller is usually used at the control layer (e.g. Struts2 actions) to identify the control layer class as a Spring Bean, which has the same functionality as @component. 5) @AutoWired is used to annotate Bean attribute variables, attribute Set methods and constructors, and cooperate with the corresponding annotation processor to complete the automatic configuration of Bean. The default assembly is based on the type of Bean. 6) @Resource works like Autowired. The difference is that @AutoWired is assembled by default by Bean type, while @Resource is assembled by default by Bean instance name.

There are two important attributes in @resource: name and type.

Spring resolves the name attribute to the Bean instance name and the Type attribute to the Bean instance type. If the name attribute is specified, assembly is performed by instance name; If the type attribute is specified, assembly is performed by Bean type.

If neither is specified, the Bean instance name is used for assembly. If no match is found, the Bean type is used for assembly. If can’t match, the thrown NoSuchBeanDefinitionException anomalies. 7) the @Qualifier annotation, used in conjunction with the @AutoWired annotation, changes the default assembly by Bean type to assembly by the instance name of the Bean, which is specified by the @Qualifier annotation parameter.

case

1) Dao layer implementation class

@Repository("userDao")  // Persistent layer component annotations
public class UserDaoImpl implements UserDao {
    @Override
    public void add(a) {
        System.out.println("Dao layer add() method..."); }}Copy the code

2) Service layer implementation class

@Service("userService")
public class UserServiceImpl implements UserService {
    @Resource(name = "userDao")
    private UserDao userDao;

    // public void setUserDao(UserDao userDao) {
    // this.userDao = userDao;
    // }
    
    @Override
    public void add(a) {
        userDao.add();
        System.out.println("Service layer add() method..."); }}Copy the code

3) the Annotation layer

@Controller("userAction")
public class UserAction {
    @Resource(name = "userService")
    private UserService userService;

    // public void setUserService(UserService userService) {
    // this.userService = userService;
    // }
    public void add(a){
        userService.add();
        System.out.println("Action layer add() method..."); }}Copy the code

4) XML configuration files


      
<beans xmlns="http://www.springframework.org/schema/beans"
       xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
       xmlns:context="http://www.springframework.org/schema/context"
       xsi:schemaLocation="Http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans-2.5.xsd http://www.springframework.org/schema/context http://www.springframework.org/schema/context/spring-context.xsd">
    <! Tell Spring to scan Java files containing component annotations in the specified package.
    <context:component-scan base-package="com.lyl.*"/>
</beans>
Copy the code

5) Test classes

public static void main(String[] args) {
        ApplicationContext context = new ClassPathXmlApplicationContext("applicationContext.xml");
        UserAction userAction = (UserAction) context.getBean("userAction");
        userAction.add();
    }
Copy the code

Print result:

Dao layer add() method... The add() method of the Service layer... Action layer add() method...Copy the code

The example above uses annotations to implement an injection bean. It can be found that there are properties in the implementation class of the Service layer and Annotation layer, but the injection can be successful even if the setter method is annotated. It shows that the injection of Annotation method can be realized without writing setter method, and the Spring container will automatically help us to achieve the injection.

If @resource (name = “userService”) is changed to @resource (name = “userService1”) at the Service layer, an error is reported. By default, @resoure is injected in byName mode. Change to @autowired and change the property name of the Service :private UserDao UserDao; Change to private UserDao userDao1; The @autoWired annotation is injected in byType mode by default.

The @qualifier annotation is used for: Simply put, the @AutoWired annotation is used, but there are multiple implementation classes using the same interface, and since the default is byType, Spring doesn’t know what we need to inject. We can use @qualifier to call the byName pattern to tell Spring that we need to inject the bean.


Constructor for annotation injection

In addition to Setter annotation injection, member variable annotation injection, there is a more important “constructor injection”.

The constructor has multiple parameters of the same type, and Spring can’t tell the difference between argument passing and assignment. It took me a long time to find this problem, but I didn’t know what to do with it. I tried to use @qualifier to solve the problem, because I could inject it according to the byName mode. However, I failed to use @Resource in the constructor and started a long journey to Baidu. The @qualifier annotation was placed in front of the constructor parameter, and the result was Run correctly. On reflection, we found that the nature of our problem was that Spring could not recognize the passing and assignment of our arguments. Using @qualifier was the right way to go. It is placed in front of the parameter to indicate that the parameter uses the byName pattern and to indicate which BeanName is used, so that you can understand the solution to the problem in this particular case.

The code is as follows:

@Controller("userAction")
public class UserAction {
    private UserService userService1;
    private UserService userService2;

    @Autowired
    public UserAction(@Qualifier("userService") UserService userService1, @Qualifier("userService1")UserService userService2) {
        this.userService1 = userService1;
        this.userService2 = userService2;
    }

    public void add(a){
        userService1.add();
        userService2.add();
        System.out.println("Action layer add() method..."); }}Copy the code

In the beginner should encounter this problem, this problem is also when I learn the annotation injection constructor temporarily thought of! If there is no multi-parameter constructor of the same type, @qualifier is generally not needed

summary

In fact, when we use annotations to help with injection, It is Spring that saves code and implements operations just as we wrote in our XML configuration file. Note that the @AutoWired and @Repository annotations use different Autowire injection modes by default. There is also the use of @autowired and @qualifier in constructors

1. Mandatory dependencies or constructor injection when the target is immutable (use constructor injection whenever possible)

2. Use setter injection for optional or variable dependencies (it is recommended to use constructors in combination with setters) 3. Avoid field injection in most cases. (I think most students might disagree, because it’s so easy to write, but its disadvantages far outweigh these advantages.)

I will refuel and learn Java. My current level is not enough and my foundation is not solid.