IoC in Spring operates bean management based on annotations

Foreword:

  • Annotation is a code special mark, format: @note name (attribute name=attribute value, attribute name=attribute value...)
  • Use annotations, annotations are applied to classes, methods, and attributes
  • Purpose of using annotations: simplify xml configuration

1. The annotations provided in Spring for Bean management creation objects

The following four annotation functions are the same and can be used to create bean instances

  • @Component
  • @Service
  • @Controller
  • @Repository

Steps:
1. Turn on 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 https://www.springframework.org/schema/context/spring-context.xsd">

    <!--开启组件扫描
        1.扫描包上层目录
        2.如果扫描多个包,多个包使用逗号隔开
    -->
    <context:component-scan base-package="iocbean.byannotation"></context:component-scan>
</beans>

2. Create a class, add annotations that can create objects on the class

//在注解里面 value 属性值可以省略不写, 
// 如果不写默认值是类名称的首字母小写 例如:Person --> person
@Component(value = "person") //相当于xml配置<bean id="person" class="iocbean.byannotation.Person"></bean>
public class Person {
    
    
    private String name;
    private String age;
    private String gender;

    @Override
    public String toString() {
    
    
        return "Person{" +
                "name='" + name + '\'' +
                ", age='" + age + '\'' +
                ", gender='" + gender + '\'' +
                '}';
    }
}

Test code:

public class DemoTest {
    
    
    @Test
    public void test1(){
    
    
        ApplicationContext context = new ClassPathXmlApplicationContext("iocbean/byannotation/bean.xml");

        Person person = context.getBean("person", Person.class);

        System.out.println(person);
    }
}

Output result:

Person{name='null', age='null', gender='null'}

Process finished with exit code 0

2. Component scan details configuration

  • use-default-filters="false" means that the default filter is not used now, configure the filter yourself; context:include-filter, set what content to scan
  • context:exclude-filter: set what content will not be scanned

Among them, there are several types of type: annotation, aspectj, assignable, custom, and regex.
Its meaning is as follows:

  • annotation: annotation type
  • assignable_type: annotation: the specified type
  • aspectj: According to the expression of Aspectj, basically not used
  • regex: According to regular expressions
  • custom: custom rule

Example configuration file:

<?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 https://www.springframework.org/schema/context/spring-context.xsd">

    <!--开启组件扫描
        1.扫描包上层目录
        2.如果扫描多个包,多个包使用逗号隔开
    -->
    <context:component-scan base-package="iocbean.byannotation"></context:component-scan>


    <!--示例 1
        use-default-filters="false" 表示现在不使用默认 filter,
        自己配置 filter context:include-filter ,设置扫描哪些内容
    -->
    <context:component-scan base-package="iocbean.byannotation" use-default-filters="false">
        <context:include-filter type="annotation" expression="org.springframework.stereotype.Service"></context:include-filter>
    </context:component-scan>

    <!--示例 2
        下面配置扫描包所有内容 context:exclude-filter: 设置哪些内容不进行扫描
    -->
    <context:component-scan base-package="iocbean.byannotation">
        <context:exclude-filter type="annotation" expression="org.springframework.stereotype.Controller"></context:exclude-filter>
    </context:component-scan>
</beans>

Three. Annotation to achieve attribute injection

1. @Autowired: Automatic assembly according to attribute type

@Component
public class Student {
    
    
    
    // 添加注入属性注解
    @Autowired
    //定义 Person 类型属性 
    // 不需要添加 set 方法 
    private Person person;

    @Override
    public String toString() {
    
    
        return "Student{" +
                "person=" + person +
                '}';
    }
}

2.@Qualifier: inject according to the name

The @Qualifier annotation needs to be used with @Autowired above

    //添加注入属性注解
    @Autowired //根据类型进行注入
    @Qualifier(value = "person")//根据名称进行注入
    //定义 Person 类型属性
    // 不需要添加 set 方法
    private Person person1;

3.@Resource: can be injected according to the type, can be injected according to the name

In fact, @Resource is not an annotation of Spring. Its package is javax.annotation.Resource, which needs to be imported, but Spring supports the injection of this annotation.
The @Resource annotation belongs to J2EE and is assembled by name by default. The name can be specified through the name attribute.

  • If the name attribute is not specified, when the annotation is written on the field, the field name is used for name search by default.
  • If the name attribute is not specified, when the annotation is written on the setter method, the attribute name is used for assembly by default.
  • If the name attribute is not specified, the assembly is performed according to the type when no bean matching the name is found.
  • It should be noted that if the name attribute is specified, it will only be assembled according to the name.

Recommended use: @Resource annotation is on the field, and this annotation belongs to J2EE, which reduces the coupling with spring. The most important thing is that the code looks more elegant.
It should be noted that the higher version of JDK fails to assemble when using @Resource annotation, and the bean assembly succeeds after using @Autowired() and @Qualifier("") instead. In the development of using Spring annotations, there are two solutions when using @Resource to report a null pointer exception:

  1. Use jdk8
  2. Import a new jar package of javax.annotation

For example, the content of the javax.annotation.* package in my JDK12 version is as follows:
Insert picture description here
you can see that there is no Resource annotation class, and then I re-import javax.annotation-api-1.3.2.jar, and after completion, the following is as follows:
Insert picture description here
so we can use @Resource annotations The
code example:

    @Resource//根据类型进行注入
    private Person person;

    @Resource(name = "person1") //根据名称进行注入
    private Person person3;

4.@Value: Inject common type attributes

    @Value(value = "19")
    private String age;

5.@Autowired(required=false)

By default, the dependent object must exist. If you want to allow a null value, you can set its required attribute to false.
That is, sometimes the dependent object does not exist, and the injection will fail. When we do not add required=false, an exception will occur. When we add the parameter (required=false), if the injection fails, the null value will be injected automatically at this time, and no error will be reported.
Code example:

    @Autowired(required = false)
    private Person person;
    
    
    @Autowired(required = false) //根据类型进行注入
    @Qualifier(value = "person1")//根据名称进行注入
    private Person person1;

Four. Configuration

Create configuration class instead of xml configuration file

//作为配置类,替代xml配置文件
@Configuration
//定义扫描的路径,从中找出标识了需要装配的类自动装配到spring的bean容器中
@ComponentScan("iocbean.byannotation/complete_annotation")
public class SpringIocConfig {
    
    
}

Person class:

@Component
public class Person {
    
    
    @Value("Mr.Yu")
    private String name;
    @Value("21")
    private String age;
    @Value("男")
    private String gender;

    public Person() {
    
    
        System.out.println("Person类构造器");
    }

    @Override
    public String toString() {
    
    
        return "Person{" +
                "name='" + name + '\'' +
                ", age='" + age + '\'' +
                ", gender='" + gender + '\'' +
                '}';
    }
}

Student class:

@Component
public class Student {
    
    
    @Autowired(required = false)
    private Person person;

    @Autowired(required = false)
    @Qualifier("person")
    private Person person1;

    @Resource
    private Person person2;

    public Student() {
    
    
        System.out.println("Student类构造器");
    }

    @Override
    public String toString() {
    
    
        return "Student{" +
                "person=" + person +
                ", person1=" + person1 +
                ", person2=" + person2 +
                '}';
    }
}

Test code:

public class DemoTest {
    
    
    @Test
    public void test1(){
    
    
        ApplicationContext context = new AnnotationConfigApplicationContext(SpringIocConfig.class);

        Student student = context.getBean("student", Student.class);

        System.out.println(student);
    }
}

Output result:

Person类构造器
Student类构造器
Student{person=Person{name='Mr.Yu', age='21', gender='男'}, person1=Person{name='Mr.Yu', age='21', gender='男'}, person2=Person{name='Mr.Yu', age='21', gender='男'}}

Process finished with exit code 0

Guess you like

Origin blog.csdn.net/MrYushiwen/article/details/111301755