tia 此次实现会比较简单,围绕着Aware感知事件的处理,所谓Aware感知通俗说明就是将applicationContext、beanFactory、beanName、beanClassLoader等等的IOC的容器对象传给用户,使用户能够获取该对象并进行使用的操作。
那么就要考虑如何传给用户,怎么合理设计,让用户得到容器对象
1.工程目录
等待上传中
2.xml类图
2.1.Aware接口
定义了Aware接口,这个接口就是标记的,如果任何继承此接口则代表是感知接口,统一判断对象是不是Aware条件也可使用
2.2 BeanFactoryAware
定义了BeanFactoryAware接口,此接口继承Aware,并定义方法为setBeanFactory(BeanFactory beanFactory);,此方法可用户实现
2.3 BeanNameAware
定义了BeanNameAware接口,此接口继承Aware,并定义方法为setBeanName(String beanName);,此方法可用户实现
2.4 BeanClassLoaderAware
定义了BeanClassLoaderAware接口,此接口继承Aware,并定义方法为setBeanClassLoader(ClassLoader classLoader);,此方法可用户实现。
2.5 ApplicationContextAware
定义了ApplicationContextAware接口,此接口继承Aware,并定义方法为setApplicationContext(ApplicationContext? applicationContext);,此方法可用户实现。
2.6?ApplicationContextAwareProcessor
定义一个ApplicationContextAwareProcessor类,实现BeanPostProcessor接口,这样的好处是原本咱们上节已经有了bean对象实例化后可以处理后置bean的情况,那么可以通过此进行使用。
2.7?AbstractApplicationContext
添加到beanPostProcessor集合里,并且调用ApplicationContextAwareProcessor包装类的构造方法将当前applicationContext对象放入到包装类里留着bean初始化之后调用自定义方法
2.8?AbstractAutowireCapableBeanFactory
将之前的初始化方法里添加判断是否是Aware的操作,调用具体的用户自定义的方法
3.代码实现
? ?Aware:添加Aware标志接口
// 定义标记接口,实现该接口可以被spring感知
// 就像是一种标签一样,可以统一方便摘取出属于此类接口的实现类,通常会有instanceof一起判断使用
public interface Aware {
}
?添加BeanFactoryAware接口定义BeanFactory的感知
// 特点:此接口类继承Aware接口类
// 实现此接口,就能感知到所属的beanFactory
public interface BeanFactoryAware extends Aware{
void setBeanFactory(BeanFactory beanFactory);
}
添加BeanNameAware接口定义BeanName的感知
// 实现此接口,就能感知到所属的beanName
public interface BeanNameAware extends Aware {
void setBeanName(String name);
}
添加BeanClassLoaderAware接口定义beanClassLoader的感知
// 实现此接口,既能感知到所属的ClassLoader
public interface BeanClassLoaderAware extends Aware {
void setBeanClassLoader(ClassLoader classLoader);
}
在xontext包下添加ApplicationContextAware,用来对ApplicationContext感知
// 实现此接口,就能感知到所属的ApplicationContext
public interface ApplicationContextAware extends Aware {
void setApplicationContext(ApplicationContext applicationContext);
}
添加ApplicationContextAwareProcessor包装类,这个主要是在ApplicationContext得到的时候使用注册添加集合数据里,通过构造方法获取ApplicationContext ,在初始化之后将此实例传给用户的操作。
// ApplicationContextAware包装处理类,主要原因是ApplicationContext所创建对象时机和beanFactoryAware等不在一块,
// 通过此类的postProcessBeforeInitialization在初始化后调用此方法来交给用户自定义赋值setApplicationContext方法得到
// ApplicationContext对象
public class ApplicationContextAwareProcessor implements BeanPostProcessor {
private final ApplicationContext applicationContext;
public ApplicationContextAwareProcessor(ApplicationContext applicationContext) {
this.applicationContext = applicationContext;
}
@Override
public Object postProcessBeforeInitialization(Object bean, String beanName) {
if (bean instanceof ApplicationContextAware) {
((ApplicationContextAware) bean).setApplicationContext(applicationContext);
}
return bean;
}
@Override
public Object postProcessAfterInitialization(Object bean, String beanName) {
return bean;
}
}
AbstractApplicationContext的修改添加了一个这段代码? “beanFactory.addBeanPostProcessor(new ApplicationContextAwareProcessor(this));”就ok了
public abstract class AbstractApplicationContext extends DefaultResourceLoader implements ConfigurableApplicationContext {
// 使用模板方法
@Override
public void refresh() {
// 1.创建beanFactory
// 2.将创建完的beanFactory和配置文件路径传输到资源处理器里
// 3.从资源处理器获取输入流,根据流解析bean以及属性数据并注册到bean容器里
refreshBeanFactory();
// 2.获取beanFactory
ConfigurableListableBeanFactory beanFactory = getBeanFactory();
// 3.将当前AbstractApplicationContext对象通过构造方法赋值传给包装类
beanFactory.addBeanPostProcessor(new ApplicationContextAwareProcessor(this));
// 4.在bean实例化之前,执行BeanFactoryPostProcessor(Invoke factory processors registered as beans in the context)
// 4.1 根据BeanFactoryPostProcessor来判断是否是自定义实现子类,是就创建bean,并注册到单例类(创建自定义类Bean(MyBeanFactoryPostProcessor))
// 4.2 根据得到的BeanFactoryPostProcessor接口来调用postProcessBeanFactory方法(此时beanDefinition里的属性已经修改)
invokeBeanFactoryPostProcessors(beanFactory);
// 5.BeanPostProcessor需要提前于其他Bean对象实例化之前执行注册操作
// 5.1 通过getBeansOfType()找到与BeanPostProcessor相关的类,
// 5.2 找到以后调用将当前的BeanPostProcessor放入集合里(做标识-后续其他bean实例创建可进行后置处理更改对象bean)
registerBeanPostProcessors(beanFactory);
// 6.提前实例化单例bean对象
// 通过beanDefinationMap里的实例对象将后续bean实例进行实例化,并处理后置修改的对象
beanFactory.preInstantiateSingletons();
}
protected abstract void refreshBeanFactory();
protected abstract ConfigurableListableBeanFactory getBeanFactory();
// 在bean实例化之前,执行BeanFactoryPostProcessor,自定义实现进行bean的修改
private void invokeBeanFactoryPostProcessors(ConfigurableListableBeanFactory beanFactory) {
// 获取和BeanFactoryPostProcessor类有关系的的类-这里主要是获取BeanFactoryPostProcessor的子实现接口
Map<String, BeanFactoryPostProcessor> beanPostProcessorMap = beanFactory.getBeansOfType(BeanFactoryPostProcessor.class);
for (BeanFactoryPostProcessor beanFactoryPostProcessor : beanPostProcessorMap.values()) {
// 调用用户自定义实现的子接口
beanFactoryPostProcessor.postProcessBeanFactory(beanFactory);
}
}
private void registerBeanPostProcessors(ConfigurableListableBeanFactory beanFactory) {
// 根据BeanPostProcessor获取其子实现接口
Map<String, BeanPostProcessor> beanPostProcessorMap = beanFactory.getBeansOfType(BeanPostProcessor.class);
for (BeanPostProcessor beanPostProcessor : beanPostProcessorMap.values()) {
// 将beanPostProcessor添加到集合里
beanFactory.addBeanPostProcessor(beanPostProcessor);
}
}
@Override
public void registerShutdownHook() {
System.out.println("进行registerShutdownHook()注册钩子方法!");
// 在程序正常退出或jvm进行关闭时调用传输进来的线程对象方法,此次调用本类里close()方法。
Runtime.getRuntime().addShutdownHook(new Thread(this::close));
}
@Override
public void close() {
System.out.println("程序执行完毕,可以调用close()方法,进行用户自定义销毁工作!");
getBeanFactory().destroySingletons();
}
@Override
public <T> Map<String, T> getBeansOfType(Class<T> type) {
return getBeanFactory().getBeansOfType(type);
}
@Override
public String[] getBeanDefinitionNames() {
return getBeanFactory().getBeanDefinitionNames();
}
@Override
public Object getBean(String name) throws BeansException {
return getBeanFactory().getBean(name);
}
@Override
public Object getBean(String name, Object... args) {
return getBeanFactory().getBean(name, args);
}
@Override
public <T> T getBean(String name, Class<T> requiredType) throws BeansException {
return getBeanFactory().getBean(name, requiredType);
}
}
AbstractAutowireCapableBeanFactory这个类我就不把全部的展示出来了,就展示initializeBean方法,这个方法主要是添加了如下几个if判断,如果是这些感知实现调用用户实现方法,将参数传给外界
private Object initializeBean(String beanName, Object bean, BeanDefinition beanDefinition) {
if (bean instanceof Aware){
if (bean instanceof BeanFactoryAware){
// 设置当前BeanFactory
((BeanFactoryAware) bean).setBeanFactory(this);
}
if (bean instanceof BeanNameAware){
// 设置容器中bean的名称
((BeanNameAware) bean).setBeanName(beanName);
}
if (bean instanceof BeanClassLoaderAware){
((BeanClassLoaderAware) bean).setBeanClassLoader(getBeanClassLoader());
}
}
// 1. 执行 BeanPostProcessor Before 处理
Object wrappedBean = applyBeanPostProcessorsBeforeInitialization(bean, beanName);
// 执行自定义初始化方法invokeInitMethods(beanName, wrappedBean, beanDefinition);
try {
invokeInitMethods(beanName, wrappedBean, beanDefinition);
} catch (Exception e) {
e.printStackTrace();
throw new BeansException("Invocation of init method of bean [" + beanName + "] failed", e);
}
// 2. 执行 BeanPostProcessor After 处理
wrappedBean = applyBeanPostProcessorsAfterInitialization(wrappedBean, beanName);
return wrappedBean;
}
4.测试准备
还是上一节的配置文件以及UserDao,只有userService发生变化,需要实现aware感知,将值进行赋值操作,并且我将值打印出来,方便大家观看
public class UserService implements BeanFactoryAware, ApplicationContextAware, BeanNameAware, BeanClassLoaderAware {
private String uId;
private String company;
private UserDao userDao;
private String location;
private ApplicationContext applicationContext;
private BeanFactory beanFactory;
private String beanName;
private ClassLoader classLoader;
@Override
public void setBeanClassLoader(ClassLoader classLoader) {
this.classLoader = classLoader;
System.out.println("this.classLoader="+classLoader);
}
@Override
public void setBeanFactory(BeanFactory beanFactory) {
this.beanFactory = beanFactory;
System.out.println("this.beanFactory="+beanFactory);
}
@Override
public void setBeanName(String name) {
this.beanName = name;
System.out.println("this.beanName="+name);
}
@Override
public void setApplicationContext(ApplicationContext applicationContext) {
this.applicationContext = applicationContext;
System.out.println("this.applicationContext="+applicationContext);
}
public void queryUserInfo() {
System.out.println("查询用户信息:" + userDao.queryUserName(uId)
+ ",公司名称:" + company + ",地址:" + location);
}
/*@Override
public void destroy() throws Exception {
System.out.println("执行接口实现方式的DisposableBean:UserService.destroy");
}
@Override
public void afterPropertiesSet() {
System.out.println("执行接口实现方式的InitializingBean:UserService.afterPropertiesSet");
}*/
public String getuId() {
return uId;
}
public void setuId(String uId) {
this.uId = uId;
}
public UserDao getUserDao() {
return userDao;
}
public void setUserDao(UserDao userDao) {
this.userDao = userDao;
}
public String getLocation() {
return location;
}
public void setLocation(String location) {
this.location = location;
}
public String getCompany() {
return company;
}
public void setCompany(String company) {
this.company = company;
}
public ApplicationContext getApplicationContext() {
return applicationContext;
}
public BeanFactory getBeanFactory() {
return beanFactory;
}
public String getBeanName() {
return beanName;
}
public ClassLoader getClassLoader() {
return classLoader;
}
}
添加单元测试:
public class ApiTest {
//
@Test
public void test_xml() {
// 1.初始化BeanFactory
ClassPathXmlApplicationContext applicationContext = new ClassPathXmlApplicationContext("classpath:spring.xml");
applicationContext.registerShutdownHook();
// 2.获取bean对象调用方法
UserService userService = applicationContext.getBean("userService", UserService.class);
userService.queryUserInfo();
System.out.println("BeanClassLoaderAware:" + userService.getApplicationContext());
System.out.println("BeanFactoryAware:" + userService.getBeanFactory());
}
}
运行以后测试情况如下:说明容器数据已经给到用户了。
?
|