Spring -- configuring bean s based on annotations

Posted by TRB on Tue, 30 Nov 2021 10:03:04 +0100

1, Create Dao, Service and Controller respectively through annotations

1. Why use annotations?

If you configure according to the previous xml method, multiple beans need to be configured one by one. When these beans are particularly numerous and complex, the configuration one by one is not in line with human nature (laziness), then annotations will arise spontaneously. When we create a bean class, we only need to gracefully add a line of light annotations to the class name, and a bean is loaded into the bean space.

2. Four annotations representing components (beans)

  • Controller: the presentation layer controller component identifies a control layer controller component managed by the Spring IOC container (which can be understood as a servlet)
  • Service: business logic layer component, which identifies a business logic layer component managed by Spring IOC container (can be understood as a service)
  • Repository: a persistence layer component that identifies a persistence layer component managed by the Spring IOC container (which can be understood as Dao)
  • Component: a common component that identifies a Spring IOC (anything can be represented)

Component naming rules

① Default: use the string obtained after the initial lowercase of the component's simple class name as the bean id

② Use the value attribute of the Component annotation to specify the bean id. note: in fact, Spring does not have the ability to identify whether a component is the type it marks. Even if the @ repository annotation is used on a presentation layer controller component, it will not produce any errors. It can be seen that these components are not much different, but only for the logical distinction of programs.

2, Scan component

After these components are annotated, if they are not scanned, they cannot enter the bean management space. Before scanning components, you need to introduce configuration

xmlns:context="http://www.springframework.org/schema/context"

Add the scanned root directory to the xml

<context:component-scan base-package="com.shang.component"/>

This adds these components.

1.<context:include-filter>The child node represents the target class to include
	Note: it is usually necessary to use-default-filters Property can achieve the effect of "only some components". That is, by use-default-filters Property is set to false, Disable the default filter and scan only include-filter The component specified by the rule in.
2.<context:exclude-filter> Node represents the target class 3 to be excluded.component-scan You can have several include-filter and exclude-filter node
categoryExampleexplain
annotationcom.shang.XxxAnnotationFilter all classes marked with xxannotation. This rule filters according to whether the target component is annotated with annotations of the specified type.
assignablecom.shang.BaseXxxFilter all subclasses of BaseXxx class. This rule filters whether the target component is a subclass of the specified type.
aspectjcom.shang.*Service+All class names end with Service, or subclasses of such a class. This rule filters based on AspectJ expressions.
regexcom.shang.anno.*All classes under the com.atguigu.anno package. This rule filters according to the class name matched by the regular expression.
customcom.shang.XxxTypeFilterUse the XxxTypeFilter class to customize the filtering rules by encoding. This class must implement the org.springframework.core.type.filter.TypeFilter interface

3, Use @ autowired annotation to realize automatic assembly according to type

First, create three MVC pattern classes:

@Controller
public class BookServlet {

    @Autowired
    private BookService bookService;

    public void save() {
        bookService.save();
    }
}

@Service
public class BookService {
    @Autowired
    private BookDao bookDao;

    public void save() {
        System.out.println("Calling bookDao.sava()");
        bookDao.sava();
    }
}

@Repository
public class BookDao {

    public void sava() {
        System.out.println("BookDao Saving book--");
    }
}

Make such a configuration in xml

<?xml version="1.0" encoding="UTF-8"?>
<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.xsd
       http://www.springframework.org/schema/context
       http://www.springframework.org/schema/context/spring-context-4.3.xsd">

    <context:component-scan base-package="com.shang"></context:component-scan>
</beans>

Call method

ConfigurableApplicationContext applicationContext = new ClassPathXmlApplicationContext("beans04.xml");
@Test
public void test01() {
    BookServlet bookServlet = applicationContext.getBean(BookServlet.class);
    bookServlet.save();
}

Something magical happened,

Calling bookDao.sava()
BookDao Saving book--

The member type is injected, and the set method is not used. This is a very magical point. It is found by consulting the data.

In the reflection mechanism of java, there is a method setAccessible(boolean) method. If it is set to true, we can directly access private members and change these values directly.

After the @ Autowired annotation is added, Spring will automatically turn off the access control check of this member, so there is no need to set()

4, There is more than one bean of resource type. How to assemble autowired

@Autowired principle:

  • First, find the corresponding component in the container according to the type
    • Find one and assign it
    • Not found, throw exception
    • Find more than one, and continue to match according to the variable name as the id

example:

@Service
public class BookService {
    @Autowired
    private BookDao bookDao;

    public void save() {
        System.out.println("BookService");
        bookDao.sava();
    }
}
@Service
public class BookServiceExt extend BookService{
    @Autowired
    private BookDao bookDao;

    @Override
    public void save() {
        System.out.println("BookServiceExt---");
    }
}

1. First call: inject BookService

 @Autowired
 private BookService bookService;

output

BookService
BookDao Saving book--

2. For the second call, inject BookServiceExt

 @Autowired
 private BookServiceExt bookServiceExt;

output

BookServiceExt---
BookDao Saving book--

3. The third call injects BookService, but only puts BookServiceExt into the container

output

BookServiceExt---
BookDao Saving book--

4.@Qualifier custom injection

At this point, you can provide the bean name in the @ Qualifier annotation. Spring even allows you to annotate the @ Qualifier annotation on the formal parameters of the method to specify the name of the injected bean.

@Autowired
public void hahaha(@Qualifier("bookServiceExt")BookService bookservice) {
   System.out.println(bookservice);
}

5, The difference between @ Autowired, @ Resource and @ Inject

  • @Autowired annotation: the most powerful

  • @Resource: annotation j2ee; java standard, more extensible. It is required to provide a bean name attribute. If the attribute is empty, the variable or method name at the label will be automatically used as the bean name.

  • @Inject: @ inject, like the @ Autowired annotation, injects matching bean s by type, but does not have the reqired attribute.

Topics: Java Spring