I heard that wechat search “Java fish” will change strong oh!

This article is posted on Github and Gitee, and contains my entire Java series of articles for study and interview purposes

(1) What is Bean

Beans in Spring are simply Java objects managed by the Spring container. When we write a class, the class is just a pure Java class, which can be created in the new way. When we add this class to the Spring container, it becomes a Bean that is managed by the Spring container and can be used by automatic injection.

How do I add beans to the Spring container

Here are four common ways to add beans.

@bean: The most common way to add a Bean when writing a normal class

@ComponentScan + @Controller @service @Component @repository: SpringBoot: ComponentScan + @Controller @service @Component @repository

@import: Inject beans by importing them

4, @ ImportBeanDefinitionRegister: similar to the Import, you can specify the name of the Bean

(3) Scope of Bean

The @bean annotation declares that this class is a Bean. Prior to Spring5, most of the declaration was put into the configuration file, and after Spring5, it was done with two annotations. Take the Teacher class for example

public class Teacher {}@Configuration
public class MainConfig {
    @Bean
    public Teacher teacher(a){
        return newTeacher(); }}Copy the code

Without specifying @Scope, all instances of beans are singleton beans and are handedly loaded (created when the container starts). Lazy loading (which is loaded when called) can be implemented with the @lazy annotation.

@Bean
//@Lazy
public User user(a){
    return new User();
}
Copy the code

Specifying @scope to prototype means multiple instances and lazy loading (created when used)

@Bean
@Scope(value = "prototype")
public User user(a){
    return new User();
}
Copy the code

List the other Bean scopes:

Prototype Multiple instances Request One request session One session levelCopy the code

(4) Common annotations of beans

There are several annotations that are often used with @beans

4.1 Conditional

Conditional annotations mean conditions, which are valid only if conditions are met. For example, I configure Conditional in my Bean:

@Bean
@Conditional(value = TeacherCondition.class)
public Teacher teacher(a){
    return new Teacher();
}
Copy the code

TeacherCondition code is as follows: Return true if Spring has a Bean named Student, false otherwise

public class TeacherCondition implements Condition {
    public boolean matches(ConditionContext conditionContext, AnnotatedTypeMetadata annotatedTypeMetadata) {
        if (conditionContext.getBeanFactory().containsBean("student")) {return true;
        }
        return false; }}Copy the code

The result is that if TeacherCondition returns true, the teacher bean will be registered with the container, otherwise it will not be.

4.2 ComponentScan

This annotation is associated with Controller, Service, etc. After adding Controller, Service, etc., to a class, you need to add ComponentScan to the configuration class. Controller and Service annotations are available only when scanned by ComponentScan:

@Configuration
// The most basic scanning path mode
//@ComponentScan(basePackages = {"com.javayz.testcompentscan"})
// Add the Filter method
@ComponentScan(basePackages = {"com.javayz.testcompentscan"},includeFilters = { @ComponentScan.Filter(type = FilterType.ANNOTATION,value = {Controller.class, Service.class}), @ComponentScan.Filter(type = FilterType.CUSTOM,value = {TestFilterType.class}) },useDefaultFilters = false)
public class MainConfig {

    @Bean
    @Scope(value = "prototype")
    public User user(a){
        return newUser(); }}Copy the code

ANNOTATION indicates that only the ANNOTATION set here will be scanned. Filtertype. CUSTOM is a CUSTOM Filter, and TestFilterType does the following: Classes under the package name DAO are registered in the Bean container

public class TestFilterType implements TypeFilter {
    public boolean match(MetadataReader metadataReader, MetadataReaderFactory metadataReaderFactory) throws IOException {
        // Get the class source information for the current class
        ClassMetadata classMetadata = metadataReader.getClassMetadata();
        if (classMetadata.getClassName().contains("dao")) {return true;
        }
        return false; }}Copy the code

4.3 @ Import

@import can be used to Import third-party components from a container, and can also serve the same purpose as @bean:

@Configuration
//@Import(value = {Teacher.class, Student.class})
//@Import(value = {MyImportSelector.class})
@Import(value = {MyBeanDefinitionRegister.class})
public class MainConfig {}Copy the code

The first way is to import the corresponding class directly, which is the same as writing @bean directly

@Import(value = {Teacher.class, Student.class})
Copy the code

The second way to import the ImportSelector object is to return the fully qualified name of the Bean to be imported via the selectImports method:

public class MyImportSelector implements ImportSelector {
    public String[] selectImports(AnnotationMetadata annotationMetadata) {
        return new String[]{"com.javayz.testimport.compent.Teacher"}; }}Copy the code

A third way to inject beans via BeanDefinitionRegister (you can specify Bean names)

public class MyBeanDefinitionRegister implements ImportBeanDefinitionRegistrar {
    public void registerBeanDefinitions(AnnotationMetadata importingClassMetadata, BeanDefinitionRegistry registry) {
        RootBeanDefinition rootBeanDefinition = new RootBeanDefinition(Student.class);
        registry.registerBeanDefinition("student",rootBeanDefinition); }}Copy the code

The most common scenario for Import annotations is SpringBoot automatic injection. You can see the @import annotation in SpringBoot automatic injection source code export.

(v) Bean initialization and destruction

When the container manages the Bean’s life cycle, we can make a Bean execute its own methods at initialization and destruction by specifying the Bean methods’ initialization and destruction methods ourselves.

1. Customize initialization methods and destruction methods

public class Teacher {
    public Teacher(a){
        System.out.println("Teacher construction method");
    }
    public void init(a){
        System.out.println("Teacher initialization method");
    }
    public void destory(a){
        System.out.println("Teacher Destruction Method"); }}@Configuration
public class MainConfig {
    @Bean(initMethod = "init",destroyMethod = "destory")
    public Teacher teacher(a){
        return newTeacher(); }}Copy the code

When the singleton container is started, the bean object is created, and when the container is destroyed, the bean’s destruction method is called.

For multi-instance beans, the bean is not created when the container is started, it is created when the bean is retrieved, and bean destruction is not managed by the IOC container.

2, through the InitializingBean, DisposableBean interface

Spring’s two interfaces also provide initialization and destruction.

public class Student implements InitializingBean.DisposableBean {
    public Student(a){
        System.out.println("Student constructor");
    }
    @Override
    public void destroy(a) throws Exception {
        System.out.println("Student destroyed");
    }
    @Override
    public void afterPropertiesSet(a) throws Exception {
        System.out.println("Student initialization"); }}@Configuration
public class MainConfig {
    @Bean
    public Student student(a){
        return newStudent(); }}Copy the code

3, BeanPostProcessor

BeanPostProcessor is called before and after the initialization of all beans

@Component
public class MyBeanPostProcessor implements BeanPostProcessor {
    @Override
    public Object postProcessBeforeInitialization(Object bean, String beanName) throws BeansException {
        System.out.println("Before Bean initialization");
        return bean;
    }

    @Override
    public Object postProcessAfterInitialization(Object bean, String beanName) throws BeansException {
        System.out.println("After Bean initialization");
        returnbean; }}@ComponentScan
@Configuration
public class MainConfig {
    @Bean(initMethod = "init",destroyMethod = "destory")
    public Teacher teacher(a){
        return new Teacher();
    }
    @Bean
    public Student student(a){
        return newStudent(); }}Copy the code

(6) Summary

Although the concept of beans sounds simple, there is a lot of content in them. One of the cores of Spring is IOC, which is managing beans. I’m fish boy. See you next time!