SpringBoot框架(4)-- 类装配及Bean装配监听器
1、普通方式装配类对象
(1)添加带有@Bean注解的方法
User.java(带@Component注解)
package com.demo.boot.bootenable.beanDemo1; import org.springframework.stereotype.Component; @Component
public class User {
}
User.java
(2)需要装配的类添加@Component注解
Book.java(不带@Component注解)
package com.demo.boot.bootenable.beanDemo1; public class Book {
}
Book.java
==》打印
package com.demo.boot.bootenable.beanDemo1; import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
import org.springframework.context.ConfigurableApplicationContext;
import org.springframework.context.annotation.Bean; /**
* 普通方式装配类对象
* (1)添加带有@Bean注解的方法
* (2)需要装配的类添加@Component注解
*/
@SpringBootApplication
public class BootEnableApplication { @Bean
public Book createBook(){
return new Book();
} public static void main(String[] args) {
ConfigurableApplicationContext context = SpringApplication.run(com.demo.boot.bootenable.beanDemo1.BootEnableApplication.class);
User user = context.getBean(User.class);
System.out.println(user); Book book = context.getBean(Book.class);
System.out.println(book);
context.close();
}
}
main方法
com.demo.boot.bootenable.beanDemo1.User@3301500b
com.demo.boot.bootenable.beanDemo1.Book@24b52d3e
2、使用@Import方式装配类对象
准备两个测试类User.java和Book.java
package com.demo.boot.bootenable.beanDemo2; public class User {
}
User.java
package com.demo.boot.bootenable.beanDemo2; public class Book {
}
Book.java
(1)方式1==》@Import({User.class,Book.class}) //直接添加需要装配的类
==》代码结构
package com.demo.boot.bootenable.beanDemo2; import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
import org.springframework.context.ConfigurableApplicationContext;
import org.springframework.context.annotation.Import; /**
* 使用@Import方式装配类对象
*/
@SpringBootApplication
@Import({User.class,Book.class})//方式1==》直接添加需要装配的类
public class BootEnableApplication {
public static void main(String[] args) {
ConfigurableApplicationContext context2 = SpringApplication.run(BootEnableApplication.class);
User user = context2.getBean(User.class);
System.out.println(user); Book book = context2.getBean(Book.class);
System.out.println(book);
context2.close();
}
}
Application.java
==》输出
com.demo.boot.bootenable.beanDemo2.User@24855019
com.demo.boot.bootenable.beanDemo2.Book@3abd581e
(2)方式2==》@Import(BeanImportSelector.class) //BeanImportSelector重写ImportSelector类的selectImport方法
==》代码结构
package com.demo.boot.bootenable.beanDemo2; import org.springframework.context.annotation.ImportSelector;
import org.springframework.core.type.AnnotationMetadata; public class BeanImportSelector implements ImportSelector {
@Override
public String[] selectImports(AnnotationMetadata annotationMetadata) {
return new String[]{
"com.demo.boot.bootenable.beanDemo2.Book",
"com.demo.boot.bootenable.beanDemo2.User"
};
}
}
BeanImportSelector.java
package com.demo.boot.bootenable.beanDemo2; import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
import org.springframework.context.ConfigurableApplicationContext;
import org.springframework.context.annotation.Import; /**
* 使用@Import方式装配类对象
*/
@SpringBootApplication
//@Import({User.class,Book.class})//方式1==》直接添加需要装配的类
@Import(BeanImportSelector.class)//方式2==》BeanImportSelector重写ImportSelector类的selectImport方法
public class BootEnableApplication {
public static void main(String[] args) {
ConfigurableApplicationContext context2 = SpringApplication.run(BootEnableApplication.class);
User user = context2.getBean(User.class);
System.out.println(user); Book book = context2.getBean(Book.class);
System.out.println(book);
context2.close();
}
}
Application.java
==》输出
com.demo.boot.bootenable.beanDemo2.User@88d6f9b
com.demo.boot.bootenable.beanDemo2.Book@47d93e0d
(3)方式3==》@Import(MyBeanDefinitionRegistrar.class) //MyBeanDefinitionRegistrar重写ImportBeanDefinitionRegistrar类的registerBeanDefinitions方法
==》代码结构
package com.demo.boot.bootenable.beanDemo3; import org.springframework.beans.factory.config.BeanDefinition;
import org.springframework.beans.factory.support.BeanDefinitionBuilder;
import org.springframework.beans.factory.support.BeanDefinitionRegistry;
import org.springframework.context.annotation.ImportBeanDefinitionRegistrar;
import org.springframework.core.type.AnnotationMetadata; /**
* ImportBeanDefinitionRegistrar可以为装配对象添加额外的属性
*/
public class MyBeanDefinitionRegistrar implements ImportBeanDefinitionRegistrar {
@Override
public void registerBeanDefinitions(AnnotationMetadata annotationMetadata, BeanDefinitionRegistry beanDefinitionRegistry) {
BeanDefinitionBuilder userBDB = BeanDefinitionBuilder.rootBeanDefinition(User.class);
BeanDefinition userBD = userBDB.getBeanDefinition();
beanDefinitionRegistry.registerBeanDefinition("user",userBD); BeanDefinitionBuilder bookBDB = BeanDefinitionBuilder.rootBeanDefinition(Book.class);
BeanDefinition bookBD = bookBDB.getBeanDefinition();
beanDefinitionRegistry.registerBeanDefinition("book",bookBD);
}
}
MyBeanDefinitionRegistrar.java
package com.demo.boot.bootenable.beanDemo3; import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
import org.springframework.context.ConfigurableApplicationContext;
import org.springframework.context.annotation.Import; /**
* 使用@Import方式装配类对象
*/
@SpringBootApplication
//@Import({User.class,Book.class})//方式1==》直接添加需要装配的类
//@Import(BeanImportSelector.class)//方式2==》BeanImportSelector重写ImportSelector类的selectImport方法
@Import(MyBeanDefinitionRegistrar.class)//方式3==》MyBeanDefinitionRegistrar重写ImportBeanDefinitionRegistrar类的registerBeanDefinitions方法
public class BootEnableApplication {
public static void main(String[] args) {
ConfigurableApplicationContext context3 = SpringApplication.run(BootEnableApplication.class);
User user = context3.getBean("user", User.class);
System.out.println(user); Book book = context3.getBean("book", Book.class);
System.out.println(book);
context3.close();
}
}
Application.java
==》输出
com.demo.boot.bootenable.beanDemo3.User@4d0402b
com.demo.boot.bootenable.beanDemo3.Book@2fa7ae9
备注:以上demo中,都是指定需要装配的类,不指定则不会自动自动装配
3、Bean装配监听器
bean在装配过程中会执行一系列方法,其中有postProcessBeforeInitialization --> afterPropertiesSet --> init-method -- > postProcessAfterInitialization。
(1)postProcessBeforeInitialization方法,在bean初始化之前执行
(2)afterPropertiesSet方法,初始化bean的时候执行
(3)nit-method方法,初始化bean的时候执行
(4)postProcessAfterInitialization方法,在bean初始化之后执行。
因此,我们可以在装配时,进行拦截处理。这里demo选用重写postProcessBeforeInitialization方法
代码结构
3.1 创建类 MyBeanDefinitionProcessor继承BeanPostProcessor,添加属性packages的构造器,并重写postProcessBeforeInitialization方法,实现类装配前打印。
package com.demo.boot.bootenable.smple; import org.springframework.beans.BeansException;
import org.springframework.beans.factory.config.BeanPostProcessor; import java.util.ArrayList; public class MyBeanDefinitionProcessor implements BeanPostProcessor { private ArrayList<String> packages; public ArrayList<String> getPackages() {
return packages;
} public void setPackages(ArrayList<String> packages) {
this.packages = packages;
} @Override
public Object postProcessBeforeInitialization(Object bean, String beanName) throws BeansException { for (String pack : packages) {
if (bean.getClass().getName().startsWith(pack)) {
System.out.println("instance name:" + bean.getClass().getName());
}
}
return bean;
}
}
MyBeanDefinitionProcessor
3.2 创建类ScannerPackegeRegistar implements ImportBeanDefinitionRegistrar,重写registerBeanDefinitions方法,把自定义的MyBeanDefinitionProcessor注册进去。
package com.demo.boot.bootenable.smple; import org.springframework.beans.factory.support.BeanDefinitionBuilder;
import org.springframework.beans.factory.support.BeanDefinitionRegistry;
import org.springframework.context.annotation.ImportBeanDefinitionRegistrar;
import org.springframework.core.type.AnnotationMetadata;
import org.springframework.stereotype.Component; import java.util.Arrays;
import java.util.List; @Component
public class ScannerPackegeRegistar implements ImportBeanDefinitionRegistrar {
/**
* 注册实体对象被装配前回调方法
* @param annotationMetadata
* @param beanDefinitionRegistry
*/
@Override
public void registerBeanDefinitions(AnnotationMetadata annotationMetadata, BeanDefinitionRegistry beanDefinitionRegistry) {
String[] strArr = (String[]) annotationMetadata
.getAnnotationAttributes(EnableScanner.class.getName())
.get("packages"); List<String> packages = Arrays.asList(strArr);
System.out.println(packages);
BeanDefinitionBuilder dbd = BeanDefinitionBuilder.rootBeanDefinition(MyBeanDefinitionProcessor.class);
dbd.addPropertyValue("packages", packages); beanDefinitionRegistry.registerBeanDefinition(MyBeanDefinitionProcessor.class.getName(), dbd.getBeanDefinition());
} }
ScannerPackegeRegistar.java
3.3 自定义注解EnableScanner
package com.demo.boot.bootenable.smple; import org.springframework.context.annotation.Import;
import java.lang.annotation.*; @Target({ElementType.TYPE})
@Retention(RetentionPolicy.RUNTIME)
@Documented
@Import(ScannerPackegeRegistar.class)
public @interface EnableScanner {
String[] packages();
}
EnableScanner.java
3.4 创建Person.java、Student.java和UserVO.java类
package com.demo.boot.bootenable.smple.bean; import org.springframework.stereotype.Component; @Component
public class Person {
}
Person.java
package com.demo.boot.bootenable.smple.bean; import org.springframework.stereotype.Component; @Component
public class Student {
}
Student.java
package com.demo.boot.bootenable.smple.vo; import org.springframework.stereotype.Component; @Component
public class UserVO {
}
UserVO.java
3.5 Application
package com.demo.boot.bootenable.smple; import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
import org.springframework.context.ConfigurableApplicationContext; @SpringBootApplication
@EnableScanner(packages = {"com.demo.boot.bootenable.smple.bean", "com.demo.boot.bootenable.smple.vo"})//启用监控扫描类的注解
public class ScannerPackegeApplication {
public static void main(String[] args) {
ConfigurableApplicationContext context = SpringApplication.run(ScannerPackegeApplication.class, args); context.close();
}
}
Application.java
输出结果
instance name:com.demo.boot.bootenable.smple.bean.Person
instance name:com.demo.boot.bootenable.smple.bean.Student
instance name:com.demo.boot.bootenable.smple.vo.UserVO
总结思路
1、把类装配到SpringBoot容器管理主要分两大类
(1)普通方式:直接在类上加@Component注解,或者在创建对象方法加上@Bean注解
(2)通过@Import注解:直接指定需要装配的类,传入
重写ImportSelector类的selectImport方法的类,
或重写ImportBeanDefinitionRegistrar类的registerBeanDefinitions方法
2、Bean装配监听器
(1)定义注解,接受需要装配类的包名
(2)创建ImportBeanDefinitionRegistrar的子类ScannerPackegeRegistar,重写registerBeanDefinitions方法,作用是把监听器注册到SpringBoot初始化Bean的过程中。
(3)创建BeanPostProcessor的子类MyBeanDefinitionProcessor,重写postProcessBeforeInitialization方法,作用是监听在bean初始化前装配的类。
最新文章
- 安装 Visual Studio Web Tools 的奇怪问题
- mybatis动态切换数据源
- JavaScript + SVG实现Web前端WorkFlow工作流DAG有向无环图
- Jquery网页加载进度条(随笔,当然要随便写,当日记动态心情写咯)
- action中result没有值
- Odoo Entypo Regular Icon List
- codeforce 603B - Moodular Arithmetic
- 同步窗体移动 FormMove
- const和violate
- JQuery 图片延迟加载并等比缩放插件
- 学习MVC遇到的问题
- PyMOTW: heapq¶
- C# 读取IE缓存文件(2)
- SQL server 行转列 列转行
- java byte 梳理
- oracle 优化方法总结
- EF Core
- Less入门与安装(转)
- js定位当前位置的坐标经纬度和地点名称和天气
- 对va_list; va_start ; va_end ;vsprintf理解(转)