Spring:IOC/DI annotation development and management of third-party bean s

Spring past review

🍭SSM framework 01: IoC and DI of Spring, and take you to create Spring core configuration files
🍭 SSM framework 02: Learn Spring configuration files from 0-1
🍭 Why learn Spring? Learn what? How to learn?
🍭How does Spring implement IOC and DI? Introduction to case analysis
🍭 Explain all the IOC knowledge points of Spring in ten thousand words
🍭 Explain DI related contents in detail and master DI configuration and use
🍭 Spring master IOC/DI configuration management third-party bean s
🍭 Spring core container environment configuration, creation, dependency injection, etc
🍭 Spring master IOC/DI annotation to manage third-party bean s

Today's goal

  • Master IOC/DI annotation management of third-party bean s

1, IOC/DI annotation development management third-party bean s

When defining bean s, you need to write an annotation on your own developed classes. However, if it is a third-party class and these classes are in the jar package, we can't add an annotation on the class. What should we do at this time?

In case of the above problems, we need to have a more flexible way to define beans. This way can not write annotations on the original code, but can also define beans. This uses a new annotation = = @Bean==.

How should this annotation be used?

Let's use the annotation of the data source managed in the configuration mode again, and learn about the use of @Bean through this case.

1.1 environmental preparation

Prepare the environment before learning the @Bean annotation:

  • Create a Maven project

  • pom.xml to add Spring dependency

    <dependencies>
        <dependency>
            <groupId>org.springframework</groupId>
            <artifactId>spring-context</artifactId>
            <version>5.2.10.RELEASE</version>
        </dependency>
    </dependencies>
    
  • Add a configuration class SpringConfig

    @Configuration
    public class SpringConfig {
    }
    
  • Add BookDao, BookDaoImpl classes

    public interface BookDao {
        public void save();
    }
    @Repository
    public class BookDaoImpl implements BookDao {
        public void save() {
            System.out.println("book dao save ..." );
        }
    }
    
  • Create a running App

    public class App {
        public static void main(String[] args) {
            AnnotationConfigApplicationContext ctx = new AnnotationConfigApplicationContext(SpringConfig.class);
        }
    }
    

The final project structure is as follows:

1.2 annotation development management third-party bean s

Complete the management of Druid data source in the above environment. The specific implementation steps are as follows:

Step 1: import the corresponding jar package

<dependency>
    <groupId>com.alibaba</groupId>
    <artifactId>druid</artifactId>
    <version>1.1.16</version>
</dependency>

Step 2: add a method in the configuration class

Note that the return value of this method is the Bean object type to be created

@Configuration
public class SpringConfig {
    public DataSource dataSource(){
        DruidDataSource ds = new DruidDataSource();
        ds.setDriverClassName("com.mysql.jdbc.Driver");
        ds.setUrl("jdbc:mysql://localhost:3306/spring_db");
        ds.setUsername("root");
        ds.setPassword("root");
        return ds;
    }
}

Step 3: add @Bean annotation on the method

@The function of bean annotation is to make the return value of a method as a bean object managed by Spring

@Configuration
public class SpringConfig {
	@Bean
    public DataSource dataSource(){
        DruidDataSource ds = new DruidDataSource();
        ds.setDriverClassName("com.mysql.jdbc.Driver");
        ds.setUrl("jdbc:mysql://localhost:3306/spring_db");
        ds.setUsername("root");
        ds.setPassword("root");
        return ds;
    }
}

Note: DataSource ds = new DruidDataSource() cannot be used

Because there is no corresponding setter method in the DataSource interface to set properties.

Step 4: get the object from the IOC container and print it

public class App {
    public static void main(String[] args) {
        AnnotationConfigApplicationContext ctx = new AnnotationConfigApplicationContext(SpringConfig.class);
        DataSource dataSource = ctx.getBean(DataSource.class);
        System.out.println(dataSource);
    }
}

So far, the case of using @bean to manage third-party beans has been completed.

If there are multiple beans to be managed by Spring, you can directly add more methods in the configuration class and add @Bean annotation to the methods.

1.3 importing external configuration classes

If all third-party beans are configured into Spring's configuration class SpringConfig, although it is OK, it is not conducive to code reading and classification management. So we wonder whether we can configure these beans into different configuration classes according to their categories?

For data source bean s, we create a new JdbcConfig configuration class and configure the data source under this class.

public class JdbcConfig {
	@Bean
    public DataSource dataSource(){
        DruidDataSource ds = new DruidDataSource();
        ds.setDriverClassName("com.mysql.jdbc.Driver");
        ds.setUrl("jdbc:mysql://localhost:3306/spring_db");
        ds.setUsername("root");
        ds.setPassword("root");
        return ds;
    }
}

The question now is, how can this configuration class be loaded by the Spring configuration class and create a DataSource object in the IOC container?

There are two solutions to this problem:

1.3.1 using package scan import

Step 1: add package scanning on Spring's configuration class
@Configuration
@ComponentScan("com.itheima.config")
public class SpringConfig {
	
}
Step 2: add configuration annotation on JdbcConfig

The JdbcConfig class should be put into com itheima. Config package, which needs to be scanned by the Spring configuration class

@Configuration
public class JdbcConfig {
	@Bean
    public DataSource dataSource(){
        DruidDataSource ds = new DruidDataSource();
        ds.setDriverClassName("com.mysql.jdbc.Driver");
        ds.setUrl("jdbc:mysql://localhost:3306/spring_db");
        ds.setUsername("root");
        ds.setPassword("root");
        return ds;
    }
}
Step 3: run the program

You can still get the bean object and print the console.

Although this method can be scanned, it cannot quickly know which configuration classes are introduced. This method is not recommended.

1.3.2 Import using @Import

The implementation of the scheme is a little complicated. Spring has thought of this for a long time, so it provides us with the second scheme.

This scheme does not need to add the @Configuration annotation, but the Configuration class to be loaded must be manually imported using the @Import annotation on the Spring Configuration class

Step 1: remove the annotation on the JdbcConfig class
public class JdbcConfig {
	@Bean
    public DataSource dataSource(){
        DruidDataSource ds = new DruidDataSource();
        ds.setDriverClassName("com.mysql.jdbc.Driver");
        ds.setUrl("jdbc:mysql://localhost:3306/spring_db");
        ds.setUsername("root");
        ds.setPassword("root");
        return ds;
    }
}
Step 2: introduce in the Spring configuration class
@Configuration
//@ComponentScan("com.itheima.config")
@Import({JdbcConfig.class})
public class SpringConfig {
	
}

be careful:

  • Scan annotation can be removed

  • @The Import parameter requires an array, which can introduce multiple configuration classes.

  • @The Import annotation can only be written once in the configuration class. The following methods are not allowed

    @Configuration
    //@ComponentScan("com.itheima.config")
    @Import(JdbcConfig.class)
    @Import(Xxx.class)
    public class SpringConfig {
    	
    }
    
Step 3: run the program

You can still get the bean object and print the console

Knowledge point 1:@Bean

name@Bean
typeMethod notes
positionAbove method definition
effectSet the return value of this method as a spring managed bean
attributevalue (default): defines the id of the bean

Knowledge point 2:@Import

name@Import
typeClass annotation
positionAbove class definition
effectImport configuration class
attributevalue (default): defines the imported configuration class name,
When there are multiple configuration classes, use the array format to import multiple configuration classes at one time

1.4 annotation development implementation injects resources into third-party bean s

When using @bean to create a bean object, what if the method needs other resources during the creation process?

These resources fall into two categories: simple data types and reference data types.

1.4.1 simple data type

1.4.1.1 demand analysis

For the following code, the four elements about the database should not be written in the code, but should be read from the properties configuration file. How to optimize the following code?

public class JdbcConfig {
	@Bean
    public DataSource dataSource(){
        DruidDataSource ds = new DruidDataSource();
        ds.setDriverClassName("com.mysql.jdbc.Driver");
        ds.setUrl("jdbc:mysql://localhost:3306/spring_db");
        ds.setUsername("root");
        ds.setPassword("root");
        return ds;
    }
}
1.4.1.2 steps for injecting simple data types
Step 1: four attributes are provided in the class
public class JdbcConfig {
    private String driver;
    private String url;
    private String userName;
    private String password;
	@Bean
    public DataSource dataSource(){
        DruidDataSource ds = new DruidDataSource();
        ds.setDriverClassName("com.mysql.jdbc.Driver");
        ds.setUrl("jdbc:mysql://localhost:3306/spring_db");
        ds.setUsername("root");
        ds.setPassword("root");
        return ds;
    }
}
Step 2: use the @Value annotation to import values
public class JdbcConfig {
    @Value("com.mysql.jdbc.Driver")
    private String driver;
    @Value("jdbc:mysql://localhost:3306/spring_db")
    private String url;
    @Value("root")
    private String userName;
    @Value("password")
    private String password;
	@Bean
    public DataSource dataSource(){
        DruidDataSource ds = new DruidDataSource();
        ds.setDriverClassName(driver);
        ds.setUrl(url);
        ds.setUsername(userName);
        ds.setPassword(password);
        return ds;
    }
}
extend

The current four elements of database connection are still written in the code. What needs to be done is to raise these contents to

Get jdbc Properties configuration file. Let's think about how to implement it?

1. Add jdbc properties

2. the configuration file provides four key value pairs, which are the four elements of the database

3. use @PropertySource to load jdbc Properties configuration file

4. modify the Value of the @Value annotation attribute to ${key}. Key is the Value of the key in the key Value pair

The specific implementation will be left to everyone.

1.4.2 reference data type

1.4.2.1 demand analysis

Assuming that the BookDao object is required when building the DataSource object, how can I inject the BookDao object into the method for its use?

public class JdbcConfig {
	@Bean
    public DataSource dataSource(){
        DruidDataSource ds = new DruidDataSource();
        ds.setDriverClassName("com.mysql.jdbc.Driver");
        ds.setUrl("jdbc:mysql://localhost:3306/spring_db");
        ds.setUsername("root");
        ds.setPassword("root");
        return ds;
    }
}
1.4.2.2 steps for injecting reference data types
Step 1: scan BookDao in SpringConfig

The purpose of scanning is to enable Spring to manage bookDao, that is, to have a bookDao object in the IOC container

@Configuration
@ComponentScan("com.itheima.dao")
@Import({JdbcConfig.class})
public class SpringConfig {
}
Step 2: add parameters to the method of the JdbcConfig class
@Bean
public DataSource dataSource(BookDao bookDao){
    System.out.println(bookDao);
    DruidDataSource ds = new DruidDataSource();
    ds.setDriverClassName(driver);
    ds.setUrl(url);
    ds.setUsername(userName);
    ds.setPassword(password);
    return ds;
}

Reference type injection only needs to set formal parameters for bean definition methods, and the container will automatically assemble objects according to types.

Step 3: run the program

2, Annotation development summary

We have completed the development and implementation of XML configuration and annotation. As for the differences between them, let's compare and review them together:

Tags: Java Spring Spring Boot

Posted by readourlines on Fri, 03 Jun 2022 01:36:52 +0530