Summary of three mechanisms of spring assembly bean

The act of creating a collaborative relationship between application objects is often called wiring, which is also the essence of dependency injection (DI).

There are three most common ways to configure Spring containers :

1. Explicit configuration in XML;
2. Explicit configuration in Java;
3. Implicit bean discovery mechanism and autowiring;

Spring implements automated assembly from two perspectives:

  • Component scanning (component scanning): Spring will automatically discover the beans created in the application context.
  • Autowiring: Spring automatically meets the dependencies between beans.
    The combination of component scanning and automatic assembly can play a powerful role, they can reduce your explicit configuration to a minimum.

Ways to automate bean assembly:

First build a spring java project:
write an entity class:

package main.java.sia.knights.config.testDI;
import org.springframework.stereotype.Component;
@Component
public class Student {
    public void study(){
        System.out.println ("学生学习中。。。。");
    }
}

What you need to pay attention to is that the @Component annotation is used on the Student class. This simple annotation indicates that the class will act as a component class and tells Spring to create a bean for this class. There is no need to explicitly configure the bean, because this class uses the @Component annotation, so Spring will take care of things for you.
However, component scanning is not enabled by default. We also need to explicitly configure Spring to order it to find the class annotated with @Component and create a bean for it. The following configuration class shows the most concise configuration to accomplish this task:

package main.java.sia.knights.config.testDI;

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

@Configuration
@ComponentScan
public class ConfigScan {
}

There are two notes on this,

  • @Configuration

From Spring3.0, @Configuration is used to define the configuration class, which can replace the xml configuration file. The annotated class contains one or more methods annotated by @Bean. These methods will be scanned by AnnotationConfigApplicationContext or AnnotationConfigWebApplicationContext class To build the bean definition, initialize the Spring container.

  • @ComponentScan

The ConfigScan class does not explicitly declare any beans, except that it uses the @ComponentScan annotation, which enables
component scanning in Spring .
If there is no other configuration, @ComponentScan will scan the same package as the configuration class by default. Because the ConfigScan class is in the testDI package, Spring will scan this package and all sub-packages under this package for classes with @Component annotations. In this case, you can find the Student and automatically create a bean for it in Spring.
Test below:

package main.java.sia.knights.config.testDI;

import org.junit.Test;
import org.junit.runner.RunWith;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.test.context.ContextConfiguration;
import org.springframework.test.context.junit4.SpringJUnit4ClassRunner;

@RunWith(SpringJUnit4ClassRunner.class)
@ContextConfiguration(classes = ConfigScan.class)
public class TestDI {

    @Autowired
    public Student Student;
    
    @Test
    public void testDi(){
        Student.study ();
    }
}

TestDI uses Spring's SpringJUnit4ClassRunner to automatically create a Spring application context when the test starts. Note
@ContextConfiguration will tell it that the configuration needs to be loaded in CDPlayerConfig. Because @ComponentScan is included in the CDPlayerConfig class, the
Student bean should be included in the final application context.
Use @Autowired to get the Student bean from spring and inject it into the test code. Look at the test results: The
Insert picture description here
test results show that we have handed the student class to spring management and used it.

The following supplementary knowledge:

Name the bean scanned by the component

All beans in the Spring application context will be given an ID. In the previous example, although we did not explicitly set the ID for Student, Spring will assign an ID based on the class name. Specifically, the ID given by this bean is student, which means that the first letter of the class name is lowercase. If you want to set a different ID for this bean, all you have to do is pass the desired ID as a value to the @Component annotation. As shown in the following code:

@Component("teacher")
public class Student {
    public void study(){
        System.out.println ("学生学习中。。。。");
    }
}

There is another way to name beans, which does not use the @Component annotation, but uses the @Named annotation provided in the Java Dependency Injection specification to set the ID for the bean:

package main.java.sia.knights.config.testDI;
import javax.inject.Named;

@Named("teacher")
public class Student {
    public void study(){
        System.out.println ("学生学习中。。。。");
    }
}

Here you need to import the jar package javax.inject-1.jar, otherwise spring cannot be found, this way spring can also perform DI;

Enable component scanning via XML

Insert picture description hereCreate an xml file to enable annotation scanning, file content:

<?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.xsd">

    <context:component-scan base-package="main.java.sia.knights.config.testDI"></context:component-scan>
</beans>

Then write a configuration class to import xml:

package main.java.sia.knights.config.testDI;

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

@Configuration
@ImportResource("classpath:main/java/sia/knights/config/testDI/spring.xml")
public class ScanConfig {
}

Finally, unit test:

package main.java.sia.knights.config.testDI;

import org.junit.Test;
import org.junit.runner.RunWith;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.test.context.ContextConfiguration;
import org.springframework.test.context.junit4.SpringJUnit4ClassRunner;

@RunWith(SpringJUnit4ClassRunner.class)
@ContextConfiguration(classes = ScanConfig.class)
public class TestDI2 {

    @Autowired
    public Student Student;

    @Test
    public void testDi(){
        Student.study ();
    }
}

Similarly, the same result can be obtained.

Inject beans through xml

Add the above spring.xml file to the bean import, and comment out the automatically discovered component-scan

<?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.xsd">

    <!--<context:component-scan base-package="main.java.sia.knights.config.testDI"></context:component-scan>-->
    <bean id="student" class="main.java.sia.knights.config.testDI.Student"></bean>
</beans>

Then conduct the same test and find the effect is the same

Implementing bean assembly via java code

First look at how to write the configuration class:

package main.java.sia.knights.config.testDI;

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

@Configuration
public class KnightConfig {

  @Bean
  public Student student() {
    return new Student ();
  }
}

Test class:

package main.java.sia.knights.config.testDI;

import org.junit.Test;
import org.junit.runner.RunWith;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.test.context.ContextConfiguration;
import org.springframework.test.context.junit4.SpringJUnit4ClassRunner;

@RunWith(SpringJUnit4ClassRunner.class)
@ContextConfiguration(classes = KnightConfig.class)
public class TestDI3 {

    @Autowired
    public Student student;

    @Test
    public void testDi(){
        student.study ();
    }
}

The test results are the same, you may wish to try.

to sum up

  1. There are three main ways of assembling beans in Spring: automated configuration, explicit configuration based on Java, and explicit configuration based on XML.
  2. It is recommended to use automatic configuration as much as possible to avoid the maintenance cost caused by explicit configuration. However, if you do need to explicitly configure Spring, you should prefer Java-based configuration, which is more powerful, type-safe, and easy to refactor than XML-based configuration.

Reference: spring in action fourth edition

Published 39 original articles · won praise 1 · views 4620

Guess you like

Origin blog.csdn.net/thetimelyrain/article/details/96653037