Spring learning notes [XV] annotation programming

Posted by stan801003 on Sat, 12 Feb 2022 08:38:17 +0100

Annotation programming

01 what is annotation programming

:::info
It refers to adding specific annotations to classes or methods to complete the development of specific functions
The use of annotations is convenient for development, the code is concise, and the development speed is greatly provided
:::

02 role of annotations

:::success
Replace this configuration form of XML to simplify the configuration
:::

:::success
Replace the interface and realize the contract type of both parties
:::

Basic annotation

01 annotation scanning

In the Spring configuration file, add the tag of the component scanner to explain the location of the annotation in the project, and let Spring scan these packages to make them take effect

1. The configuration file of spring will scan the current package and its sub packages

<context:component-scan base-package="Package name"></context:component-scan>

2. How to scan multiple packages

  • Use multiple component scanners to specify different packages
  • Use delimiters; Or, split multiple package names
  • Specify parent package

1.1 troubleshooting

Exclusion policies can be superimposed

<context:component-scan base-package="Package name">
	<context:exclude-filter type="type" expression="expression"/>
</context:component-scan>
  • annotation: excludes specific annotations
    • org.springframework.stereotype. Annotation names: Service, Component, etc
  • **aspectj * *: pointcut expression. Only package pointcuts and class pointcuts are supported
  • assignable: excludes specific types
  • **regex * *: regular expression
  • **custom * *: custom exclusion policy, framework bottom layer development

1.2 inclusion method

<!-- use-default-filters="false"  :  Give Way Spring The default annotation scanning method is invalid -->
<context:component-scan base-package="Package name" use-default-filters="false">
<!--Specifies which annotation to scan-->
	<context:include-filter type="" expression="Package name"/>
</context:component-scan>

02 creating common annotations for objects

2.1 @Component

  • Function: replace the < bean > tag in the original Spring configuration file
    • id attribute: the default setting method is provided in the @ Component tag. The first letter is lowercase
    • Class attribute: get the content of class through reflection
  • The attribute value is the name of the object, which is equivalent to the id of the bean tag, and the value value is unique; If the value attribute is not specified, the id value is the lowercase initial of the word, which is provided by Spring
  • The Spring configuration file covers the annotation configuration content. In the annotation and configuration file, the id value and class value should be consistent
  • There is only one object created in the whole spring container
  • When a class is not sure what the function is, use the Component annotation

Derived annotation
:::success
In essence, these derived annotations are @ Component, and their functions, details and usage are consistent

Purpose: in order to more accurately represent the function
:::

  • @Repository: persistent layer annotation, but Spring will not use this annotation or @ Component annotation in the process of integrating Mybatis
  • @Service: used on business layer classes
  • @Controller: control layer annotation

2.2 @Scope

  1. Controls the number of times a simple object is created
  2. If it is specified as singleton, it will be created only once; This value is the default
  3. If it is specified as prototype, it will be created multiple times
  4. In XML
<bean id="userService" class="com.spring.proxy.UserServiceImpl" scope="singleton | prototype"></bean>
  1. annotation
@Service
@Scope(value = "singleton")
public class UserServiceImpl implements UserService{}

2.3 @Lazy

  1. Function: used to delay the creation of single instance objects
    • The position is above the class, provided that there is @ Component annotation
  2. Generally speaking, Spring will create all single instance objects when creating a factory
  3. be careful
    • Once the @ Lazy annotation is used, Spring will create the object when using this object
  4. XML
<bean id="userService" class="com.spring.proxy.UserServiceImpl" lazy-init="true"></bean>
  1. annotation
@Service
@Lazy
public class UserServiceImpl implements UserService{}

2.4 notes related to life cycle

:::danger
These two annotations are not provided by Spring, but by JSR520 (Java EE specification)
:::
Initialization method: @ PostConstruct

    @PostConstruct
    public void init(){
        System.out.println("User.init");
    }

Destruction method: @ PreDestroy

    @PreDestroy
    public void destroy(){
        System.out.println("User.destroy");
    }

matters needing attention

  • The annotations provided by JSR520 (Java EE specification) are not provided by Spring

03 inject relevant notes

3.1 JDK type

**@Value**
:::info
Assignment for JDK basic types
:::

1. set up xxx.properties,Configure the value of the corresponding key

2. Spring Your factory reads this configuration file  <context:property-placeholder location="Location of the configuration file"/>

3. Attribute assignment  @Value("${key}")

:::success

  • Cannot be applied to static member variables. If used, the obtained value is null
  • Collection types cannot be injected. Spring provides a new configuration form. For example, YAML, YML
    :::


**@PropertySource **
:::info
1. Used to replace the label in the configuration file < place: Property: holder "/ > in the configuration file
:::

1. set up xxx.properties

2. Apply on entity classes @PropertySource("classpath:/xxx.properties")

3. Attribute assignment @Value("${key}")

3.2 user defined types

**@Autowired **

  1. It is used for the assignment of reference type. It uses the principle of automatic injection and supports byName and byType
  2. byType automatic injection is used by default. The type of injected object must be the same as the type of target member variable or its subclass (implementation class)
  3. If you want to use byName
  • Add @ Autowired to the attribute
  • Add @ Qualifier(value="bean id") to the attribute: it means that the bean with the specified name is used to complete the assignment
  1. Attribute required
  • It is a boolean type, and the default is true. It means that the reference assignment fails, the program reports an error, and the execution is terminated
  • If it is false, it means that if the reference type assignment fails, the program will execute normally and the reference type is null
  • In general, using true can check the errors in the program as soon as possible
  1. It can be placed on the set method of the corresponding member variable, or the annotation can be directly placed on the member variable
  2. When placed on a member variable, the variable is directly assigned by reflection without calling the Set method. This method is recommended
  3. When placed on top of the set method, the set method is executed

**@Resource **

  1. The annotation from JDK is supported in Spring
  2. @Resouce(name = "") is injected based on the name, which is equivalent to the effect achieved by @ Autowired and @ Qualifier
  3. First use byName automatic injection. If byName assignment fails, byType will be used

04 thoughts on annotation development

  1. Spring annotation configuration and configuration file configuration are interconnected
  2. In the types developed by programmers, corresponding annotations can be added to create objects
  3. When applying types developed by other programmers, you still need to use the configuration file for configuration

Advanced annotation

:::success
Spring 3. Above x
:::

01 configure Bean

@Configuration

  • Used to replace XML configuration files
  • @Configuration: add this annotation to the class to become a configuration Bean; It is also a derived annotation of @ Component
  • You can use < context: component scan > for scanning, but it is not recommended
  • The content in the original XML can be solved by configuring Bean
  • After using this annotation, use AnnotationConfigApplicationContext to create a factory. If the factory reads the xml configuration file first, add @ ImportResource("location of configuration file") annotation on the configuration class
# Method 1: specify the Class of the configuration bean, and multiple factories can be specified
	ApplicationContext ac = new AnnotationConfigApplicationContext(AppConfig.class,AppConfig1.class);
	
# Method 2: specify the path where the Configuration bean is located, and the factory will scan the package to find the type with @ Configuration annotation
	ApplicationContext ac = new AnnotationConfigApplicationContext("The path of the package where the is located");

02 logback log integration

:::danger
When developing based on annotations, Log4j cannot be integrated
:::

2.1 introducing dependencies

   <dependency>
      <groupId>org.slf4j</groupId>
      <artifactId>slf4j-api</artifactId>
      <version>1.7.25</version>
    </dependency>

    <dependency>
      <groupId>org.slf4j</groupId>
      <artifactId>jcl-over-slf4j</artifactId>
      <version>1.7.25</version>
      <exclusions>
        <exclusion>
          <groupId>org.slf4j</groupId>
          <artifactId>slf4j-log4j12</artifactId>
        </exclusion>
      </exclusions>
    </dependency>

    <dependency>
      <groupId>ch.qos.logback</groupId>
      <artifactId>logback-classic</artifactId>
      <version>1.2.3</version>
    </dependency>

    <dependency>
      <groupId>ch.qos.logback</groupId>
      <artifactId>logback-core</artifactId>
      <version>1.2.3</version>
    </dependency>

    <dependency>
      <groupId>org.logback-extensions</groupId>
      <artifactId>logback-ext-spring</artifactId>
      <version>0.1.4</version>
    </dependency>

    <dependency>
      <groupId>org.slf4j</groupId>
      <artifactId>jcl-over-slf4j</artifactId>
      <version>1.7.5</version>
    </dependency>

2.2 configuration file for introducing logback

<?xml version="1.0" encoding="UTF-8" ?>
<configuration>
    <appender name="STDOUT" class="ch.qos.logback.core.ConsoleAppender">
        <encoder>
            <pattern>%d{yyyy-MM-dd HH:mm:ss.SSS} [%thread] %-5level %logger{35} - %msg %n</pattern>
        </encoder>
    </appender>

    <root level="DEBUG">
        <appender-ref ref="STDOUT" />
    </root>
</configuration>

03 @Bean

@bean annotations are used in configuration beans and are equivalent to tags in Xml configuration files

3.1 creation of objects

:::success
@Bean("id value") ----- if this id value is not specified, the method name is the id value
:::
Object creation

  • Simple object: an object that can be created directly through new
  • Complex objects: objects created directly through new

Simple object

@Bean
public Type of object created bean Medium id value(){
    // Method bodies: creating objects
     return Create a good object;
}
@Configuration
public class MyApp {
    @Bean
    public User user(){
        return new User();
    }
}


Complex object

@Bean
@Scope("singleton")//Controls the number of times an object is created
public Connection conn() {
    Connection conn = null;
    try {
        Class.forName("com.mysql.cj.jdbc.Driver");
        conn = DriverManager.getConnection(
            "jdbc:mysql://localhost:3306/chat?serverTimezone=UTC",
            "root",
            "123456");
    } catch (ClassNotFoundException | SQLException e) {
        e.printStackTrace();
    }
    return  conn;
}

3.2 type injection

3.2.1 user defined type injection

//  Mode 1
@Configuration
public class AppConfig {
    @Bean
    public UserDao userDao(){
        return new UserDaoImpl();
    }
    @Bean
    public UserService userService(UserDao userDao){
        UserServiceImpl userService = new UserServiceImpl();
        userService.setUserDao(userDao);
        return userService;
    }
}
// Mode 2
@Configuration
public class AppConfig {
    @Bean
    public User user(){
        return new User();
    }
    @Bean
    public UserMapper userMapper(){
        return new UserMapperImpl();
    }
    @Bean
    public UserService userService(){
        UserServiceImpl userService = new UserServiceImpl();
        userService.setUserMapper(userMapper());
        userService.save();
        return userService;
    }
}

3.2.2 JDK type injection

@Configuration
@PropertySource("classpath:/init.properties")
public class AppConfig {
    @Value("${id}")
    private String id;
    @Value("${name}")
    private String name;
    @Bean
    public User user(){
        User user = new User();
        user.setId(id);
        user.setName(name);
        return user;
    }
}

3.3 creation times of control objects

@Bean
@Scope("singleton | prototype") The default value is singleton

04 @ComponentScan

4.1 foundation use

  • It is used in the configuration bean, which is equivalent to the < context: component scan base package = "" > tag in the XML configuration file
  • Objective: to scan relevant annotations

4.2 use of exclusion strategy

  • Annotation method:
  • Exclude specific annotations: type = filtertype ANNOTATION, value={}
  • Exclude specific types: type = filtertype ASSIGNABLE_ TYPE , value={}
  • Pointcut expression: type = filtertype ASPECTJ, pattern=""
  • Regular expression: type = filtertype REGEX, pattern=""
  • Custom exclusion policy: type = filtertype CUSTOM, value=""
@Configuration
@ComponentScan(basePackages = "com.study",
        excludeFilters = {@ComponentScan.Filter(type = FilterType.ANNOTATION,value = {Service.class})}
)
public class AppConfig {
}

Included use strategy 3.4

@ComponentScan(basePackages = "com.frame",
                useDefaultFilters = false,
                includeFilters = {
                    @ComponentScan.Filter(type = FilterType.ANNOTATION,value = {Service.class})
                }               
)  

05 various configuration methods for creating objects in Spring Factory

5.1 multiple ways to create objects


**Method 1: @ Component**

  • It is mainly used for types developed by programmers themselves

**Method 2: @ Bean**

  • The type provided by the framework, and the type provided by other programmers

Method 3: xml configuration file

  • When integrating with legacy systems, it will not be used in the development process of pure annotation

**Method 4: @ Import**

  • Create a single object, which will be used at the bottom of the Spring framework

5.2 priority of creating multiple objects

  1. @Component and its derived annotation < @ bean < XML configuration
  2. The configuration with high priority will overwrite the annotation with low priority; If the id value is the same
  3. By configuring the priority, you can solve the coupling problem of configuration based on annotations. If you are not satisfied with a class, you can use the one with higher priority to override it

06 consolidate multiple configuration information

6.1 why are there multiple configuration information

:::info
The development of splitting multiple configuration bean s is a form of modular development, which also reflects the design idea of object-oriented performing their respective duties
:::


6.2 integration mode of multi configuration information

:::success
Multiple configuration beans
:::

  • Package scanning based on basePackages
ApplicationContext ac = new AnnotationConfigApplicationContext("Package name");
  • @Import introduces another configuration Bean into one configuration Bean, which is equivalent to < import resource = "" / >
// Select AppConfig1 as the main configuration file
@Configuration
@Import(AppConfig.class)
public class AppConfig1 {
    @Bean
    public Student student(){
        return new Student();
    }
}
// Create factory
ApplicationContext ac = new AnnotationConfigApplicationContext(AppConfig1.class);
  • When the factory is created, specify multiple class objects that configure beans
ApplicationContext ac = new AnnotationConfigApplicationContext(AppConfig1.class,AppConfig2.class);

:::success
Cross configuration injection: inject by providing member variables and using @ Autowired
:::

In the process of applying Bean configuration, no matter which method is used to summarize the configuration information, the operation method is completed by adding @ Autowired annotation to the member variable

@Configuration
@Import(AppConfig2.class)
public class AppConfig1 {
    @Autowired
    private UserMapper userMapper;
    @Bean
    public UserService userService(){
        UserServiceImpl  userService = new UserServiceImpl();
        userService.setUserMapper(userMapper);
        return userService;
    }
}



@Configuration
public class AppConfig2 {
    @Bean
    public UserMapper userMapper(){
        return new UserMapperImpl();
    }
}

:::success
Configure the integration of Bean and @ Component related annotations
:::

@Component
public class UserMapperImpl implements UserMapper{}


@Configuration
@Import(AppConfig2.class)
@ComponentScan("Annotation scanned package")
public class AppConfig1 {}

:::success
Integration of XML configuration files of configuration Bean and Spring

  • Integration of legacy systems
  • Configure override
    :::
public class UserDAOImpl implements UserDAO{
}
<bean id="userDAO" class="com.baizhiedu.injection.UserDAOImpl"/>

@Configuration
@ImportResource("applicationContext.xml")
public class AppConfig4 {
  
    @Autowired
    private UserDAO userDAO;

    @Bean
    public UserService userService() {
        UserServiceImpl userService = new UserServiceImpl();
        userService.setUserDAO(userDAO);
        return userService;
    }
}

ApplicationContext ctx = new AnnotationConfigApplicationContext(AppConfig1.class);

6.3 underlying implementation principle of Bean configuration

After Spring adds the @ Configuration annotation to the Configuration Bean, the underlying layer will perform object related Configuration processing through the proxy method of Cglib


Development of four-dimensional integration

:::info
When Spring develops a function, there are four forms. Although the development methods are different, the final effect is the same
:::

  1. Based on schema: < context: Property placeholder location = "" / >
  2. Annotation based on specific function: @ PropertySource("")
  3. Based on the original Bean tag: < Bean id = "" class = "" > < / Bean >
  4. Annotation based on @ Bean: @ Bean

Topics: Java Spring Back-end