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 |
---|---|
type | Method notes |
position | Above method definition |
effect | Set the return value of this method as a spring managed bean |
attribute | value (default): defines the id of the bean |
Knowledge point 2:@Import
name | @Import |
---|---|
type | Class annotation |
position | Above class definition |
effect | Import configuration class |
attribute | value (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: