在spring创建bean之后通过回调方法获取beanName
package com.fchan.layui.springLife;
import org.springframework.beans.factory.BeanNameAware;
import org.springframework.stereotype.Component;
@Component
public class GetSpringCreateBeanName implements BeanNameAware {
private String beanName;
@Override
public void setBeanName(String name) {
this.beanName = name;
}
}
获取创建当前bean的BeanFactory,可以利用这个beanFactory去获取到其他的bean
package com.fchan.layui.springLife;
import org.springframework.beans.BeansException;
import org.springframework.beans.factory.BeanFactory;
import org.springframework.beans.factory.BeanFactoryAware;
import org.springframework.stereotype.Component;
@Component
public class GetSpringBeanFactory implements BeanFactoryAware {
private BeanFactory beanFactory;
public void test(){
//获取其他bean,如果其他bean是单例的,这个时候获取到的bean就是spring在@Autowired时自动注入的那个bean.其实就是从容器中拿出来而已
GetSpringCreateBeanName test = (GetSpringCreateBeanName) beanFactory.getBean("getSpringCreateBeanName");
test.toString();
}
@Override
public void setBeanFactory(BeanFactory beanFactory) throws BeansException {
this.beanFactory = beanFactory;
}
}
实现InitializingBean接口对bean的初始化属性手动赋值
package com.fchan.layui.springLife;
import org.springframework.beans.factory.InitializingBean;
import org.springframework.stereotype.Component;
@Component
public class SpringInitializingBean implements InitializingBean {
private String userName;
/**
* bean的初始化
* @throws Exception
*/
@Override
public void afterPropertiesSet() throws Exception {
this.userName = "XXXXX";
}
}
BeanDefinition:
1-scope原型还是单例
2-initMethod
3-byName byType
4-dependsOn
5-beanClass(来自最开始的这个类的class,不过是可以修改的)
上面步骤串起来:
class反射----->
BeanDefinition--->
BeanFactory建造完成(只有beanFactory被建造完成之后才可以生产对象)----->
BeanFactoryPostProcessor(bean工厂的后置处理器,可以强行修改当前实现了bean工厂后置处理器的类要注入的Bean的类型,不改变beanName)------>
bean对象---->
对象属性依赖注入----->
BeanNameAware(看是否实现了这个接口,回调设置Beanname)---->
初始化(InitializingBean看是否实现了这个接口,对bean的属性进行自定义操作)------->
aop(看是否有切面,决定生成代理对象)----->
最后得到的bean对象(有aop的话这里这个bean是代理对象不是原本的bean)------->
单例池
BeanFactoryPostProcessor后置处理器修改beanDefinition和手动注册一个bean给spring的单例池
bean后置处理器接口BeanFactoryPostProcessor
就是在所有的bean被BeanDefinition定义完成后,BeanFactory建造完成之后调用.
正常来说肯定是先有beanFactory然后再有bean,在实现BeanFactoryPostProcessor接口的postProcessBeanFactory方法中,可以观察到,在获得的beanDefinition中只有当前实现BeanFactoryPostProcessor接口的class的beanDefinition,在单例池(singleObjects)中还没有去生成当前class对应的bean.只有走完了这个方法才会去生成当前class对应的对象,然后再依赖注入等后续流程
在重写的postProcessBeanFactory中可以获取某一个bean的BeanDefinition,这个时候可以强制修改这个bean的实现类型.这里强制修改BeanType之后后面Autowired自动注入这个bean就会报错了,因为BeanType被改了,变成了另一个类型
package com.fchan.layui.springLife;
import org.springframework.beans.BeansException;
import org.springframework.beans.factory.support.GenericBeanDefinition;
import org.springframework.beans.factory.config.BeanFactoryPostProcessor;
import org.springframework.beans.factory.config.ConfigurableListableBeanFactory;
import org.springframework.stereotype.Component;
@Component
public class SpringBeanFactoryPostProcessor implements BeanFactoryPostProcessor {
@Override
public void postProcessBeanFactory(ConfigurableListableBeanFactory beanFactory) throws BeansException {
GenericBeanDefinition springFactoryDemo = (GenericBeanDefinition) beanFactory.getBeanDefinition("springFactoryDemo");
System.out.println(springFactoryDemo.getBeanClassName());
//强制修改当前 SpringBeanFactoryPostProcessor bean注入进spring的类型
//springFactoryDemo.setBeanClassName(SpringInitializingBean.class.getName());
//手动注册一个bean到bean工厂中
//beanFactory.registerSingleton("xxx",new GetSpringBeanFactory());
//通过手动设置by type注入属性的方式,意味着这个bean中的属性可以不用@Autowired注解也可以by type自动注入
//不过要让这种模式生效,要让 testDesi 和 testDesi中的属性类都要被spring扫描到才行,并且要提供一下testDesi中的属性类的set方法
/**GenericBeanDefinition testDesi = (GenericBeanDefinition) beanFactory.getBeanDefinition("testDesi");
testDesi.setAutowireMode(AutowireCapableBeanFactory.AUTOWIRE_BY_TYPE);
TestDesi testDesi1 = (TestDesi) beanFactory.getBean("testDesi");
testDesi1.test();*/
}
}