1. BeanFactory-获取单例Bean
BeanFactory能干点啥? -表面上只有getBean -实际上控制反转,基本的依赖注入,直至Bean的生命周期的各种功能,都由它的实现类提供
DefaultSingletonBeanRegistry : 保存容器中的单例Bean Map
@SpringBootApplication
@Slf4j
public class SpringdemoPraApplication {
public static void main(String[] args) throws NoSuchFieldException, IllegalAccessException {
ConfigurableApplicationContext context = SpringApplication.run(SpringdemoPraApplication.class, args);
log.info("BeanFactory => {} ",context);
Field singletonObjects = DefaultSingletonBeanRegistry.class.getDeclaredField("singletonObjects");
singletonObjects.setAccessible(true);
ConfigurableListableBeanFactory beanFactory = context.getBeanFactory();
Map beanSingleObject = (Map) singletonObjects.get(beanFactory);
// beanSingleObject.forEach((k,v) -> log.info("{} ::: {}",k,v));
beanSingleObject.entrySet().
stream().
filter(e -> e.getKey().startsWith("component")).
forEach(e -> log.info("{} ::: {}",e.getKey(),e.getValue()));
}
}
2.ApplicationContext功能 2.1 MessageSourcejava.lang.reflect.Field.get(Object obj)方法返回指定对象上由此Field表示的字段的值。如果该对象具有原始类型,则该值将自动包装在对象中。 //更多请阅读:https://www.yiibai.com/javareflect/javareflect_field_get.html
提供国际化(对应语言翻译)的能力
@SpringBootApplication
@Slf4j
public class SpringdemoPraApplication {
public static void main(String[] args) throws NoSuchFieldException, IllegalAccessException {
ConfigurableApplicationContext context = SpringApplication.run(SpringdemoPraApplication.class, args);
log.info("En_Translate Hi => {} " , context.getMessage("hi",null, Locale.ENGLISH));
log.info("Ja_Translate Hi => {} " , context.getMessage("hi",null, Locale.JAPANESE));
log.info("Zh_Translate Hi => {} " , context.getMessage("hi",null, Locale.CHINESE));
}
}
2.2 ResourcePatternResolver
通配符获取资源
@SpringBootApplication
@Slf4j
public class SpringdemoPraApplication {
public static void main(String[] args) throws NoSuchFieldException, IllegalAccessException, IOException {
ConfigurableApplicationContext context = SpringApplication.run(SpringdemoPraApplication.class, args);
Resource[] resources = context.getResources("classpath*:application.yml");
for (Resource resource : resources) {
log.info("resource => {}",resource);
}
}
}
2.3 EnvironmentCapable
获取配置信息或者环境变量
@SpringBootApplication
@Slf4j
public class SpringdemoPraApplication {
public static void main(String[] args) throws NoSuchFieldException, IllegalAccessException, IOException {
ConfigurableApplicationContext context = SpringApplication.run(SpringdemoPraApplication.class, args);
String java_home = context.getEnvironment().getProperty("JAVA_HOME");
log.info("java_home => {}",java_home);
String server_port = context.getEnvironment().getProperty("server.port");
log.info("server.port => {}",server_port);
}
}
2.4 ApplicationEventPublisher
事件发布 , 用于Bean之间的解耦
事件源
public class UserRegisterEventPublisher extends ApplicationEvent {
public UserRegisterEventPublisher(Object source) {
super(source);
}
}
发布事件
@SpringBootApplication
@Slf4j
public class SpringdemoPraApplication {
public static void main(String[] args) throws NoSuchFieldException, IllegalAccessException, IOException {
ConfigurableApplicationContext context = SpringApplication.run(SpringdemoPraApplication.class, args);
context.publishEvent(new UserRegisterEventPublisher(context));
}
}
监听器-Email : 任何 Bean 都可以接收事件
@Component
@Slf4j
public class UserRegEmail {
@EventListener
public void registerByEmail(UserRegisterEventPublisher eventPublisher){
log.info("收到事件 执行发邮件进行用户注册");
}
}
监听器-SMS: 任何 Bean 都可以接收事件
@Component
@Slf4j
public class UserRegSMS {
@EventListener
public void registerBySMS(UserRegisterEventPublisher eventPublisher){
log.info("收到事件 执行发短信进行用户注册");
}
}
3.BeanFactory实现 3.1 后置处理器
BeanFactoryBeanPostProcessor : 添加BeanFactory的后处理 , 来给beanFactory增添解析注解的能力 @Configuration , @Bean
BeanBeanPostProcessor : 添加Bean的后处理 , 来给beanFactory增添增强生命周期增强的方法 , 可以进行依赖注入 , 能够解析 @Autowired , @Resources
-
beanDefinitionName => org.springframework.context.annotation.internalConfigurationAnnotationProcessor
-
beanFactory的后置处理器 , 添加解析@Configuration , @Bean的能力
-
-
beanDefinitionName => org.springframework.context.annotation.internalAutowiredAnnotationProcessor
-
bean后置处理器 , 添加解析 @Autowired的能力
-
-
beanDefinitionName => org.springframework.context.annotation.internalCommonAnnotationProcessor
-
bean后置处理器 , 添加解析 @Resoureces的能力
-
-
beanDefinitionName => org.springframework.context.event.internalEventListenerProcessor
-
beanDefinitionName => org.springframework.context.event.internalEventListenerFactory
public class TestBeanFactory {
public static void main(String[] args) {
DefaultListableBeanFactory beanFactory = new DefaultListableBeanFactory();
AbstractBeanDefinition beanDefinition = BeanDefinitionBuilder.genericBeanDefinition(SpringConfig.class).setScope("singleton").getBeanDefinition();
beanFactory.registerBeanDefinition("beanDefinition",beanDefinition);
//添加beanFactory的处理器
AnnotationConfigUtils.registerAnnotationConfigProcessors(beanFactory);
//beanFactoryPostProcessor
beanFactory.getBeansOfType(BeanFactoryPostProcessor.class).
values().
forEach(beanFactoryPostProcessor -> beanFactoryPostProcessor.postProcessBeanFactory(beanFactory));
//beanPostProcessor
beanFactory.getBeansOfType(BeanPostProcessor.class).
values().
forEach(beanPostProcessor -> beanFactory.addBeanPostProcessor(beanPostProcessor));
BeanOne beanOne = beanFactory.getBean(BeanOne.class);
for (String beanDefinitionName : beanFactory.getBeanDefinitionNames()) {
System.err.println("beanDefinitionName => " + beanDefinitionName);
}
//饿加载
beanFactory.preInstantiateSingletons();
System.err.println("beanTwo => " + beanOne.getBeanTwo());
}
}
3.2 后置处理器执行顺序
同一属性上如果同时加入依赖注入注解 @Autowired , @Resoureces 时注入类型的优先级.
System.out.println("CommonAnnotationBeanPostProcessor 优先级 => "+ (Ordered.LOWEST_PRECEDENCE -3) );
System.out.println("CommonAnnotationBeanPostProcessor 优先级 => "+ (Ordered.LOWEST_PRECEDENCE -2) );
4.ApplicationContext实现
4.1 ClassPathXmlApplicationContext
@Slf4j
public class TestApplicationContext {
public static void main(String[] args) {
DefaultListableBeanFactory beanFactory = new DefaultListableBeanFactory();
log.info(" <<<<<<<<<<<<<<<<<<<<<<<< 读取之前");
for (String beanDefinitionName : beanFactory.getBeanDefinitionNames()) {
log.info("beanDefinitionName => " + beanDefinitionName);
}
log.info(" <<<<<<<<<<<<<<<<<<<<<<<< 读取之后");
XmlBeanDefinitionReader reader = new XmlBeanDefinitionReader(beanFactory);
reader.loadBeanDefinitions(new ClassPathResource("bean01.xml"));
for (String beanDefinitionName : beanFactory.getBeanDefinitionNames()) {
log.info("beanDefinitionName => " + beanDefinitionName);
}
}
}
4.2 FileSystemXmlApplicationContext
略
4.3 AnnotationConfigApplicationContext较为经典的容器 , 基于java配置类来创建
@Slf4j
public class TestApplicationContext {
public static void main(String[] args) {
ApplicationContext context = new AnnotationConfigApplicationContext(SpringConfig.class);
for (String beanDefinitionName : context.getBeanDefinitionNames()) {
System.err.println("beanDefinitionName => " + beanDefinitionName);
}
System.err.println("bean2.bean1 => " + context.getBean("beanTwo", BeanTwo.class).getBeanOne());
}
}
BeanTwo.java
public class BeanTwo {
private BeanOne beanOne;
public void setBeanOne(BeanOne beanOne) {
this.beanOne = beanOne;
}
public BeanOne getBeanOne() {
return beanOne;
}
}
BeanOne.java
public class BeanOne {}
4.4 AnnotationConfigServletWebServerApplicationContext
较为经典的容器 , 基于java配置类来创建 , 用于web环境
WebConfig
@Configuration
public class WebConfig {
@Bean
public ServletWebServerFactory servletWebServerFactory(){
return new TomcatServletWebServerFactory();
}
@Bean
public DispatcherServlet dispatcherServlet(){
return new DispatcherServlet();
}
@Bean
public DispatcherServletRegistrationBean registrationBean(DispatcherServlet dispatcherServlet){
return new DispatcherServletRegistrationBean(dispatcherServlet,"/");
}
@Bean("/hello")
public Controller controllerOne(){
return (request, response) -> {
response.getWriter().println("hello");
return null;
};
}
}
serverStarter : 8080
public class TestAnnotationConfigConfigServletWebServerApplicationContext {
public static void main(String[] args) {
AnnotationConfigServletWebServerApplicationContext context =
new AnnotationConfigServletWebServerApplicationContext(WebConfig.class);
}
}
请求 : localhost:8080/hello
5.Bean生命周期 5.1 bean生命周期
构造=>依赖注入=>Bean初始化=>Bean销毁
LifeCycleBean.java
@Component
@Slf4j
public class LifeCycleBean {
public LifeCycleBean() { log.info("1 => 构造 LifeCycle()");}
@Autowired
public void autowire(@Value("${JAVA_HOME}") String javaHome){
log.info("2 => 依赖注入 : {}",javaHome);
}
@PostConstruct
public void init(){
log.info("3 => Bean初始化");
}
@PreDestroy
public void destroy(){
log.info("4 => Bean销毁");
}
}
SpringBootRun
@SpringBootApplication
public class Springdemo2Application {
public static void main(String[] args) {
ConfigurableApplicationContext context = SpringApplication.run(Springdemo2Application.class, args);
context.close();
}
}
5.2 Bean后处理器
提供bean生命周期各个阶段的扩展
@Slf4j
@Component
public class MyBeanPostProcessor implements InstantiationAwareBeanPostProcessor , DestructionAwareBeanPostProcessor {
@Override
public void postProcessBeforeDestruction(Object bean, String beanName) throws BeansException {
if(beanName.equals("lifeCycleBean")){
log.info("<<<<<< 销毁之前执行 , 如@PreDestory");
}
}
@Override
public Object postProcessBeforeInstantiation(Class> beanClass, String beanName) throws BeansException {
if(beanName.equals("lifeCycleBean")){
log.info("<<<<<< 实例化之前执行 , 这里返回的对象会替换掉原本的bean");
}
//如果返回不为 null 则替换原本的bean
return null;
}
@Override
public boolean postProcessAfterInstantiation(Object bean, String beanName) throws BeansException {
if(beanName.equals("lifeCycleBean")){
log.info("<<<<<< 实例化之后执行 , 这里如果返回 false 会跳过依赖注入阶段");
//return false;
}
return true;
}
@Override
public PropertyValues postProcessProperties(PropertyValues pvs, Object bean, String beanName) throws BeansException {
if(beanName.equals("lifeCycleBean")){
log.info("<<<<<< 依赖注入阶段执行 , 如@Autowired , @Value , @Resource");
}
return pvs;
}
@Override
public Object postProcessBeforeInitialization(Object bean , String beanName) throws BeansException {
if(beanName.equals("lifeCycleBean")){
log.info("<<<<<< 初始化之前执行 , 这里返回的对象会替换掉原本的 bean , 如@PostConstruct , @ConfigurationProperties");
}
return bean;
}
@Override
public Object postProcessAfterInitialization(Object bean, String beanName) throws BeansException {
if(beanName.equals("lifeCycleBean")){
log.info("<<<<<< 初始化之后执行 , 这里返回的对象会替换掉原本的 bean , 如代理增强");
}
return bean;
}
}
6.设计模式-模板方法
提高代码的扩展能力
BeanPostProcessor.java
public interface BeanPostProcessor {
void dependencyInject(Object bean); //希望对依赖注入阶段的阶段进行扩展
}
MyBeanFactory.java
@Slf4j
public class MyBeanFactory {
private List processors = new ArrayList<>();
// 模板方法 Template Method Pattern 提高现有代码扩展能力
public Object getBean(){
Object bean = new Object();
log.info("构造 => {}" , bean);
log.info("依赖注入 => {}" , bean); //@Autowired , @Resource
for (BeanPostProcessor processor : processors) {
processor.dependencyInject(bean);
}
log.info("初始化 => {}" , bean);
return bean;
}
public void addBeanPostProcessor(BeanPostProcessor postProcessor){
processors.add(postProcessor);
}
}
TestMethodTemplate.java
@Slf4j
public class TestMethodTemplate {
public static void main(String[] args) {
MyBeanFactory beanFactory = new MyBeanFactory();
beanFactory.addBeanPostProcessor(bean -> {
log.info("加入解析@Autowired的能力");
});
beanFactory.addBeanPostProcessor(bean -> {
log.info("加入解析@Resource的能力");
});
beanFactory.getBean();
}
}
7.Bean后处理器
Bean1.java
@Slf4j
public class Bean1 {
private Bean2 bean2;
@Autowired
public void setBean2(Bean2 bean2) {
log.info("@Autowired 生效 : {} " , bean2);
this.bean2 = bean2;
}
@Autowired
private Bean3 bean3;
@Resource
public void setBean3(Bean3 bean3) {
log.info("@Resource 生效 : {}" , bean3);
this.bean3 = bean3;
}
private String home;
@Autowired
public void setHome(@Value("${JAVA_HOME}") String home) {
log.info("@Value 生效 : {}" , home);
this.home = home;
}
@PostConstruct
public void init(){
log.info("@PostConstruct 生效");
}
@PreDestroy
public void destroy(){
log.info("@PreDestroy生效");
}
@Override
public String toString() {
return "Bean1{" +
"bean2=" + bean2 +
", bean3=" + bean3 +
", home='" + home + ''' +
'}';
}
}
Bean2.java
public class Bean2 {}
Bean3.java
public class Bean3 {}
Bean4.java
@Data
@ConfigurationProperties(prefix = "java")
public class Bean4 {
private String home;
private String version;
}
TestGenericAppContext.java
@Slf4j
public class TestGenericAppContext {
public static void main(String[] args) {
//GenericApplicationContext 是一个 干净的容器
GenericApplicationContext context = new GenericApplicationContext();
//用原始的方法注册三个Bean
context.registerBean("bean1", Bean1.class);
context.registerBean("bean2", Bean2.class);
context.registerBean("bean3", Bean3.class);
context.registerBean("bean4", Bean4.class);
context.getDefaultListableBeanFactory().setAutowireCandidateResolver(new ContextAnnotationAutowireCandidateResolver());//@Value
context.registerBean(AutowiredAnnotationBeanPostProcessor.class); // 解析 @Autowired 和 @Value 的后处理器
context.registerBean(CommonAnnotationBeanPostProcessor.class); //解析 @Resource @PostConstruct @PreDestroy
ConfigurationPropertiesBindingPostProcessor.register(context.getDefaultListableBeanFactory()); //@ConfigurationProperties
//初始化容器
context.refresh(); //执行beanFactory后处理器, 添加bean后处理器 , 初始化所有单例
log.info("ConfigProper => {}",context.getBean(Bean4.class));
//销毁容器
context.close();
}
}
7.1 运行流程-AutowiredAnnotationBeanPostProcessor
@Slf4j
public class DigInAutowired {
public static void main(String[] args) throws Throwable {
DefaultListableBeanFactory beanFactory = new DefaultListableBeanFactory();
beanFactory.registerSingleton("bean2",new Bean2()); //不会执行Bean创建 , 依赖注入 , 初始化
beanFactory.registerSingleton("bean3",new Bean3());
beanFactory.setAutowireCandidateResolver(new ContextAnnotationAutowireCandidateResolver()); //@Value
beanFactory.addEmbeddedValueResolver(strVal -> new StandardEnvironment().resolvePlaceholders(strVal));//${} el表达式的解析器
//查找哪些属性 , 方法添加@Autowired , 这称之为 InjectionMetadata
AutowiredAnnotationBeanPostProcessor processor = new AutowiredAnnotationBeanPostProcessor();
processor.setBeanFactory(beanFactory);
Bean1 bean1 = new Bean1();
// log.info("获取解析@Autowired & @Value 能力之前 => {}" , bean1);
// processor.postProcessProperties(null,bean1,"bean1"); //执行依赖注入 解析@Autowired , @Value
// log.info("获取解析@Autowired & @Value 能力之后 => {}" , bean1);
Method findAutowiringMetadata =
AutowiredAnnotationBeanPostProcessor.class.getDeclaredMethod("findAutowiringMetadata", String.class, Class.class, PropertyValues.class);
findAutowiringMetadata.setAccessible(true);
InjectionMetadata metadata =
(InjectionMetadata) findAutowiringMetadata.invoke(processor, "bean1", Bean1.class, null);//获取Bean1 上 加了 @Value @Autowired 的成员变量,方法参数信息
log.info("metadata => {} ",metadata);
//调用 InjectionMetadata 来进行注入 , 注入时按类型查找值
metadata.inject(bean1,"bean1",null);
log.info("bean1 => {}" ,bean1);
}
7.2 InjectMetadata
Bean1.java
@Slf4j
public class Bean1 {
private Bean2 bean2;
@Autowired
public void setBean2(Bean2 bean2) {
log.info("@Autowired 生效 : {} " , bean2);
this.bean2 = bean2;
}
@Autowired
private Bean3 bean3;
@Resource
public void setBean3(Bean3 bean3) {
log.info("@Resource 生效 : {}" , bean3);
this.bean3 = bean3;
}
private String home;
@Autowired
public void setHome(@Value("${JAVA_HOME}") String home) {
log.info("@Value 生效 : {}" , home);
this.home = home;
}
@PostConstruct
public void init(){
log.info("@PostConstruct 生效");
}
@PreDestroy
public void destroy(){
log.info("@PreDestroy生效");
}
@Override
public String toString() {
return "Bean1{" +
"bean2=" + bean2 +
", bean3=" + bean3 +
", home='" + home + ''' +
'}';
}
}
@Slf4j
public class DigInAutowired {
public static void main(String[] args) throws Throwable {
DefaultListableBeanFactory beanFactory = new DefaultListableBeanFactory();
beanFactory.registerSingleton("bean2",new Bean2()); //不会执行Bean创建 , 依赖注入 , 初始化
beanFactory.registerSingleton("bean3",new Bean3());
beanFactory.setAutowireCandidateResolver(new ContextAnnotationAutowireCandidateResolver()); //@Value
beanFactory.addEmbeddedValueResolver(strVal -> new StandardEnvironment().resolvePlaceholders(strVal));//${} el表达式的解析器
//查找哪些属性 , 方法添加@Autowired , 这称之为 InjectionMetadata
AutowiredAnnotationBeanPostProcessor processor = new AutowiredAnnotationBeanPostProcessor();
processor.setBeanFactory(beanFactory);
Bean1 bean1 = new Bean1();
// log.info("获取解析@Autowired & @Value 能力之前 => {}" , bean1);
// processor.postProcessProperties(null,bean1,"bean1"); //执行依赖注入 解析@Autowired , @Value
// log.info("获取解析@Autowired & @Value 能力之后 => {}" , bean1);
Method findAutowiringMetadata =
AutowiredAnnotationBeanPostProcessor.class.getDeclaredMethod("findAutowiringMetadata", String.class, Class.class, PropertyValues.class);
findAutowiringMetadata.setAccessible(true);
InjectionMetadata metadata =
(InjectionMetadata) findAutowiringMetadata.invoke(processor, "bean1", Bean1.class, null);//获取Bean1 上 加了 @Value @Autowired 的成员变量,方法参数信息
log.info("metadata => {} ",metadata);
//调用 InjectionMetadata 来进行注入 , 注入时按类型查找值
metadata.inject(bean1,"bean1",null);
log.info("bean1 => {}" ,bean1);
//3.如果按类型查找值 , inject内部做的一些事情
Field bean3 = Bean1.class.getDeclaredField("bean3");
DependencyDescriptor dd1 = new DependencyDescriptor(bean3,false);
Object bean31 = beanFactory.doResolveDependency(dd1, null, null, null);
log.info(" <<<<<<<<< bean3 => {}" ,bean31);
Method setBean2 = Bean1.class.getDeclaredMethod("setBean2", Bean2.class);
DependencyDescriptor dd2 = new DependencyDescriptor(new MethodParameter(setBean2,0),false);
Object bean21 = beanFactory.doResolveDependency(dd2, null, null, null);
log.info("<<<<<<<<< bean2 => {}" ,bean21);
Method setHome = Bean1.class.getDeclaredMethod("setHome", String.class);
DependencyDescriptor dd3 = new DependencyDescriptor(new MethodParameter(setHome,0),false);
Object javaHome = beanFactory.doResolveDependency(dd3, null, null, null);
log.info("<<<<<<<<< java_home => {}" ,javaHome.toString());
}
}
8.常见工厂后处理器 8.1 @Component-ConfigurationClassPostProcessor
解析 @Component @Bean @Import @ImportResource
SpringConfig.class
@Configuration
@Slf4j
@ComponentScan("com.nanoswarm.springpra.bean")
public class SpringConfig {
@Bean
public Bean1 bean1() {return new Bean1();}
public void eat(){
log.info("eat something");
}
@Bean
public SqlSessionFactoryBean sqlSessionFactoryBean(DataSource dataSource){
SqlSessionFactoryBean sqlSessionFactoryBean = new SqlSessionFactoryBean();
sqlSessionFactoryBean.setDataSource(dataSource);
return sqlSessionFactoryBean;
}
@Bean(initMethod = "init")
public DruidDataSource dataSource(){
DruidDataSource dataSource = new DruidDataSource();
dataSource.setPassword("root");
dataSource.setUsername("root");
dataSource.setUrl("jdbc:mysql://192.168.64.140/test");
dataSource.setDriverClassName("com.mysql.cj.jdbc.Driver");
return dataSource;
}
}
Main.class
@Slf4j
public class TestDefaultListenableApp {
public static void main(String[] args) {
GenericApplicationContext context = new GenericApplicationContext();
context.registerBean("springConfig", SpringConfig.class);
context.registerBean(ConfigurationClassPostProcessor.class); //解析 @ComponentScan @Bean @Import @ImportResource
context.registerBean(MapperScannerConfigurer.class,
bd -> bd.getPropertyValues().add("basePackage","com.nanoswarm.springdemopra.bean")); //@MapperScanner
context.refresh();
for (String beanDefinitionName : context.getBeanDefinitionNames()) {
log.info("beanDefinitionName => {}" , beanDefinitionName);
}
context.close();
}
}
8.2 模拟-ConfigurationClassPostProcessor
Bean1.class
public class Bean1 {
}
Bean2.class
@Component
public class Bean2 {
}
Bean3.class
@Component
public class Bean3 {
}
Bean4.class
@Controller
public class Bean4 {
}
Config.class
@Configuration
@ComponentScan("com.nanoswarm.springdemopra.bean")
public class SpringConfig {
@Bean
public Bean1 bean1(){return new Bean1();}
}
Main.java
@Slf4j
public class TestDefaultListenableApp {
public static void main(String[] args) throws IOException {
GenericApplicationContext context = new GenericApplicationContext();
context.registerBean("springConfig", SpringConfig.class);
// context.registerBean(ConfigurationClassPostProcessor.class); //解析 @Component @Bean @Import @ImportResource
// context.registerBean(MapperScannerConfigurer.class,
// bd -> bd.getPropertyValues().add("basePackage","com.nanoswarm.springdemopra.bean")); //@MapperScanner
ComponentScan componentScan = AnnotationUtils.findAnnotation(SpringConfig.class, ComponentScan.class); //扫描这个类上的@ComponentScan注解
if(componentScan != null){
for (String path : componentScan.basePackages()) {
log.info("path => {}",path);
//com.nanoswarm.springdemopra.bean -> classpath*:/com/nanoswarm/springdemopra/bean*.class
//将包名转换为路径
String resourcePath = "classpath*:" + path.replace(".","/") + "*.class";
log.info("resourcePath => {}" , resourcePath);
CachingMetadataReaderFactory factory = new CachingMetadataReaderFactory();//解析类中的各种元素
Resource[] resources = context.getResources(resourcePath);
for (Resource resource : resources) {
//log.info(" resource => {}",resource);
MetadataReader reader = factory.getMetadataReader(resource);
log.info("类名 => {}" , reader.getClassMetadata().getClassName()); //解析类名
log.info("是否加了 @Component 注解 => {}",reader.getAnnotationMetadata().hasAnnotation(Component.class.getName())); //是否有指定注解
log.info("是否加了 @Component 派生注解 => {}" ,reader.getAnnotationMetadata().hasMetaAnnotation(Component.class.getName())); //是否有指定派生注解
}
}
}
context.refresh();
for (String beanDefinitionName : context.getBeanDefinitionNames()) {
log.info("beanDefinitionName => {}" , beanDefinitionName);
}
context.close();
}
}
8.3 自定义CompentScanPostProcessor
Main.java
@Slf4j //BeanDefinitionRegistryPostProcessor
public class ComponentScanPostProcessor implements BeanFactoryPostProcessor {
@SneakyThrows
@Override
public void postProcessBeanFactory(ConfigurableListableBeanFactory configurableListableBeanFactory) throws BeansException {
ComponentScan componentScan = AnnotationUtils.findAnnotation(SpringConfig.class, ComponentScan.class); //扫描这个类上的@ComponentScan注解
if(componentScan != null){
for (String path : componentScan.basePackages()) {
log.info("path => {}",path);
//com.nanoswarm.springdemopra.bean -> classpath*:/com/nanoswarm/springdemopra/bean*.class
String resourcePath = "classpath:" + path.replace(".","/") + "*.class";
log.info("resourcePath => {}" , resourcePath);
CachingMetadataReaderFactory factory = new CachingMetadataReaderFactory();//解析类中的各种元素
//根据路径通配符找到资源
Resource[] resources = new PathMatchingResourcePatternResolver().getResources(resourcePath);
AnnotationBeanNameGenerator generator = new AnnotationBeanNameGenerator(); //BeanName生成器
for (Resource resource : resources) {
//log.info(" resource => {}",resource);
MetadataReader reader = factory.getMetadataReader(resource);
AnnotationMetadata annotationMetadata = reader.getAnnotationMetadata();
// log.info("类名 => {}" , reader.getClassMetadata().getClassName()); //解析类名
// log.info("是否加了 @Component 注解 => {}",reader.getAnnotationMetadata().hasAnnotation(Component.class.getName())); //是否有指定注解
// log.info("是否加了 @Component 派生注解 => {}" ,reader.getAnnotationMetadata().hasMetaAnnotation(Component.class.getName())); //是否有指定派生注解
//如果加了注解 , 变成bean定义 , 加入bean工厂
if(annotationMetadata.hasAnnotation(Component.class.getName()) || annotationMetadata.hasMetaAnnotation(Component.class.getName())){
AbstractBeanDefinition bd = BeanDefinitionBuilder.genericBeanDefinition(reader.getClassMetadata().getClassName()).getBeanDefinition();
if(configurableListableBeanFactory instanceof DefaultListableBeanFactory){
DefaultListableBeanFactory beanFactory = (DefaultListableBeanFactory)configurableListableBeanFactory;
String beanName = generator.generateBeanName(bd, beanFactory);
//加入到bean工厂
beanFactory.registerBeanDefinition(beanName,bd);
}
}
}
}
}
}
}
Main.class
@Slf4j
public class TestDefaultListenableApp {
public static void main(String[] args) {
GenericApplicationContext context = new GenericApplicationContext();
context.registerBean("springConfig", SpringConfig.class);
context.registerBean(ComponentScanPostProcessor.class); //解析 @ComponentScan @Bean @Import @ImportResource
for (String beanDefinitionName : context.getBeanDefinitionNames()) {
log.info("beanDefinitionName => {}" , beanDefinitionName);
}
context.close();
}
}
8.4 工厂后处理器模拟-@Bean
simulateBeanFactory.java
@Slf4j
public class AtBeanPostProcessor implements BeanFactoryPostProcessor {
@SneakyThrows
@Override
public void postProcessBeanFactory(ConfigurableListableBeanFactory configurableListableBeanFactory) throws BeansException {
CachingMetadataReaderFactory factory = new CachingMetadataReaderFactory();
MetadataReader reader = factory.getMetadataReader(new ClassPathResource("com/nanoswarm/springpra/config/SpringConfig.class"));
Set methods = reader.getAnnotationMetadata().getAnnotatedMethods(Bean.class.getName());
for (MethodMetadata method : methods) {
log.info("method => {}" ,method.getMethodName());
String initMethod = method.getAnnotationAttributes(Bean.class.getName()).get("initMethod").toString(); //获取@Bean注解上的属性值(initMethod)
//创建BeanDefinition
BeanDefinitionBuilder builder = BeanDefinitionBuilder.genericBeanDefinition();
builder.setFactoryMethodOnBean(method.getMethodName(),"springConfig");
builder.setAutowireMode(AbstractBeanDefinition.AUTOWIRE_CONSTRUCTOR);//工厂方法参数
if(initMethod.length() > 0){
builder.setInitMethodName(initMethod);
}
AbstractBeanDefinition bd = builder.getBeanDefinition();
if(configurableListableBeanFactory instanceof DefaultListableBeanFactory){
DefaultListableBeanFactory beanFactory = (DefaultListableBeanFactory)configurableListableBeanFactory;
beanFactory.registerBeanDefinition(method.getMethodName(),bd);
}
}
}
}
Main.java
@Slf4j
public class TestBeanPostProcessor {
public static void main(String[] args) throws IOException {
GenericApplicationContext context = new GenericApplicationContext();
context.registerBean("springConfig", SpringConfig.class);
context.registerBean(AtBeanPostProcessor.class);
context.refresh();
for (String beanDefinitionName : context.getBeanDefinitionNames()) {
log.info("beanDefinitionName => {}" ,beanDefinitionName);
}
context.close();
}
}
Bean1 => null
Bean2 => @Component
Bean3 => @Component
Bean4 => @Controller
8.5 工厂后处理器模拟-@Mapper8.5.1 方式一 : 在配置类中逐个添加
SpringConfig.java
@Bean
public MapperFactoryBean mapper1(SqlSessionFactory sqlSessionFactory){
MapperFactoryBean factory = new MapperFactoryBean<>(Mapper1.class);
factory.setSqlSessionFactory(sqlSessionFactory);
return factory;
}
8.5.2 扫描mapper
MapperPostProcessor.java
public class MapperPostProcessor implements BeanDefinitionRegistryPostProcessor {
@SneakyThrows
@Override
public void postProcessBeanDefinitionRegistry(BeanDefinitionRegistry beanFactory) throws BeansException {
PathMatchingResourcePatternResolver resolver = new PathMatchingResourcePatternResolver();
Resource[] resources = resolver.getResources("classpath:com/nanoswarm/springpra/mapper*.class");
AnnotationBeanNameGenerator generator = new AnnotationBeanNameGenerator();
CachingMetadataReaderFactory factory = new CachingMetadataReaderFactory();
for (Resource resource : resources) {
MetadataReader reader = factory.getMetadataReader(resource);
ClassMetadata classMetadata = reader.getClassMetadata();
if(classMetadata.isInterface()){
AbstractBeanDefinition db = BeanDefinitionBuilder.genericBeanDefinition(MapperFactoryBean.class)
.addConstructorArgValue(classMetadata.getClassName())
.setAutowireMode(AbstractBeanDefinition.AUTOWIRE_BY_TYPE)
.getBeanDefinition();
AbstractBeanDefinition db2 = BeanDefinitionBuilder.genericBeanDefinition(classMetadata.getClassName()).getBeanDefinition();
String name = generator.generateBeanName(db2, beanFactory);
beanFactory.registerBeanDefinition(name,db);
}
}
}
@Override
public void postProcessBeanFactory(ConfigurableListableBeanFactory beanFactory) throws BeansException {
}
}
Main.java
@Slf4j
public class TestBeanPostProcessor {
public static void main(String[] args) throws IOException {
GenericApplicationContext context = new GenericApplicationContext();
context.registerBean("springConfig", SpringConfig.class);
context.registerBean(AtBeanPostProcessor.class);
context.registerBean(MapperPostProcessor.class);
context.refresh();
for (String beanDefinitionName : context.getBeanDefinitionNames()) {
log.info("beanDefinitionName => {}" ,beanDefinitionName);
}
context.close();
}
}



