手写Spring框架-笔记
参考文章:
https://github.com/DerekYRC/mini-spring
https://juejin.cn/post/6989013058035122207#heading-14
后者也是借鉴的前者哦。
当我们自己想实现一个Spring框架的时候,想想我们需要实现哪些功能。
版本V1.0 实现一个简单的Bean容器
先从最基础的部分开始,实现bean的定义、注册、获取。我们首先需要一个容器,我们可以通过这个容器获取bean。那容器里的bean是从哪来的呢?然后我们再考虑需要将bean注册到容器里面。
定义BeanFactoy作为容器,定义BeanDefinition作为bean的注册类。具体实现如下
public class BeanFactory { private Map<String, BeanDefinition> beanDefinitionMap = new ConcurrentHashMap<>(); public void registerBeanDefinition(String name, BeanDefinition obj) { beanDefinitionMap.put(name, obj); } public Object getBean(String name) { return beanDefinitionMap.get(name).getBean(); } }
public class BeanDefinition { private Object bean; public BeanDefinition(Object bean) { this.bean = bean; } public Object getBean() { return bean; } }
测试代码如下:
public class ApiTest { @Test public void test_BeanFactory(){ // 1.初始化 BeanFactory BeanFactory beanFactory = new BeanFactory(); // 2.注入bean BeanDefinition beanDefinition = new BeanDefinition(new Object()); beanFactory.registerBeanDefinition("test", beanDefinition); // 3.获取bean Object userService = beanFactory.getBean("test"); userService.toString(); } }
这样我们就获得了一个最基本的框架版本V1.0
版本V2.0 运用设计模式,实现 Bean 的定义、注册、获取
对BeanFactory进行更细致化的划分,更迭结果如下。
代码
public class BeanDefinition { private Class beanClass; public BeanDefinition(Class beanClass) { this.beanClass = beanClass; } public Class getBeanClass() { return beanClass; } public void setBeanClass(Class beanClass) { this.beanClass = beanClass; } }
public class DefaultSingletonBeanRegistry implements SingletonBeanRegistry { private final Map<String, Object> singletonObjects = new HashMap<>(); @Override public Object getSingleton(String beanName) { return singletonObjects.get(beanName); } protected void addSingleton(String beanName, Object singletonObject) { singletonObjects.put(beanName, singletonObject); } }
public abstract class AbstractBeanFactory extends DefaultSingletonBeanRegistry implements BeanFactory { @Override public Object getBean(String beanName) throws BeanException { Object bean = getSingleton(beanName); if (bean != null) { System.out.println("exist bean " + beanName); return bean; } BeanDefinition beanDefinition = getBeanDefinition(beanName); return createBean(beanName, beanDefinition); } protected abstract BeanDefinition getBeanDefinition(String beanName); protected abstract Object createBean(String beanName, BeanDefinition beanDefinition); }
public abstract class AbstractAutowireCapableBean extends AbstractBeanFactory{ @Override protected Object createBean(String beanName, BeanDefinition beanDefinition) throws BeansException { Object bean; try { bean = beanDefinition.getBeanClass().newInstance(); } catch (InstantiationException | IllegalAccessException e) { throw new BeansException("Instantiation of bean failed", e); } addSingleton(beanName, bean); return bean; } }
public class DefaultListableBeanFactory extends AbstractAutowireCapableBean implements BeanDefinitionRegistry { private final Map<String, BeanDefinition> beanDefinitionMap = new HashMap<>(); @Override public void registerBeanDefinition(String beanName, BeanDefinition beanDefinition) { beanDefinitionMap.put(beanName, beanDefinition); } @Override public BeanDefinition getBeanDefinition(String beanName) throws BeansException { BeanDefinition beanDefinition = beanDefinitionMap.get(beanName); if (beanDefinition == null) throw new BeansException("No bean named '" + beanName + "' is defined"); return beanDefinition; } }
测试代码
public class ApiTest { @Test public void test_BeanFactory(){ // 1.初始化 BeanFactory DefaultListableBeanFactory beanFactory = new DefaultListableBeanFactory(); // 2.注册 bean BeanDefinition beanDefinition = new BeanDefinition(UserService.class); beanFactory.registerBeanDefinition("userService", beanDefinition); // 3.第一次获取 bean UserService userService = (UserService) beanFactory.getBean("userService"); userService.queryUserInfo(); // 4.第二次获取 bean from Singleton UserService userService_singleton = (UserService) beanFactory.getSingleton("userService"); userService_singleton.queryUserInfo(); } }
版本V3.0 基于Cglib实现含构造函数的类实例化策略
对bean的实例化进行迭代,实现带参数的bean的实例化
BeanFactory增加带参数的getBean()方法,在实例化的时候根据配置的策略决定使用哪种方法。
public interface BeanFactory { Object getBean(String name) throws BeanException; Object getBean(String name, Object ...args) throws BeanException; }
public abstract class AbstractBeanFactory extends DefaultSingletonBeanRegistry implements BeanFactory { @Override public Object getBean(String name) throws BeansException { return doGetBean(name, null); } @Override public Object getBean(String name, Object... args) throws BeansException { return doGetBean(name, args); } protected <T> T doGetBean(final String name, final Object[] args) { Object bean = getSingleton(name); if (bean != null) { return (T) bean; } BeanDefinition beanDefinition = getBeanDefinition(name); return (T) createBean(name, beanDefinition, args); } protected abstract BeanDefinition getBeanDefinition(String beanName) throws BeansException; protected abstract Object createBean(String beanName, BeanDefinition beanDefinition, Object[] args) throws BeansException; }
public abstract class AbstractAutowireCapableBean extends AbstractBeanFactory{ private InstantiationStrategy instantiationStrategy = new CglibSubclassingInstantiationStrategy(); @Override protected Object createBean(String beanName, BeanDefinition beanDefinition, Object[] args) throws BeansException { Object bean = null; try { bean = createBeanInstance(beanDefinition, beanName, args); } catch (Exception e) { throw new BeansException("Instantiation of bean failed", e); } addSingleton(beanName, bean); return bean; } protected Object createBeanInstance(BeanDefinition beanDefinition, String beanName, Object[] args) { Constructor constructorToUse = null; Class<?> beanClass = beanDefinition.getBeanClass(); Constructor<?>[] declaredConstructors = beanClass.getDeclaredConstructors(); for (Constructor ctor : declaredConstructors) { if (null != args && ctor.getParameterTypes().length == args.length) { constructorToUse = ctor; break; } } return getInstantiationStrategy().instantiate(beanDefinition, beanName, constructorToUse, args); } public InstantiationStrategy getInstantiationStrategy() { return instantiationStrategy; } public void setInstantiationStrategy(InstantiationStrategy instantiationStrategy) { this.instantiationStrategy = instantiationStrategy; } }
public class CglibSubclassingInstantiationStrategy implements InstantiationStrategy { @Override public Object instantiate(BeanDefinition beanDefinition, String beanName, Constructor ctor, Object[] args) throws BeansException { Enhancer enhancer = new Enhancer(); enhancer.setSuperclass(beanDefinition.getBeanClass()); enhancer.setCallback(new NoOp() { @Override public int hashCode() { return super.hashCode(); } }); if (null == ctor) return enhancer.create(); return enhancer.create(ctor.getParameterTypes(), args); } }
public class SimpleInstantiationStrategy implements InstantiationStrategy { @Override public Object instantiate(BeanDefinition beanDefinition, String beanName, Constructor ctor, Object[] args) throws BeansException { Class clazz = beanDefinition.getBeanClass(); try { if (null != ctor) { return clazz.getDeclaredConstructor(ctor.getParameterTypes()).newInstance(args); } else { return clazz.getDeclaredConstructor().newInstance(); } } catch (NoSuchMethodException | InstantiationException | IllegalAccessException | InvocationTargetException e) { throw new BeansException("Failed to instantiate [" + clazz.getName() + "]", e); } } }
测试代码
public void test_BeanFactory() { // 1.初始化 BeanFactory DefaultListableBeanFactory beanFactory = new DefaultListableBeanFactory(); // 2.注入bean BeanDefinition beanDefinition = new BeanDefinition(new UserService().getClass()); beanFactory.registerBeanDefinition("userService", beanDefinition); // 3.获取bean UserService userService = (UserService) beanFactory.getBean("userService","name"); userService.queryUserInfo(); }
版本V4.0 为Bean对象注入属性和依赖Bean的功能实现
对BeanDefinition进行优化,增加propertyValue。填充bean的属性值(包含bean类型的属性值)
public class BeanDefinition { private Class beanClass; private PropertyValues propertyValues; public BeanDefinition(Class beanClass) { this.beanClass = beanClass; this.propertyValues = new PropertyValues(); } public BeanDefinition(Class beanClass, PropertyValues propertyValues) { this.beanClass = beanClass; this.propertyValues = propertyValues; } public Class getBeanClass() { return beanClass; } public void setBeanClass(Class beanClass) { this.beanClass = beanClass; } public PropertyValues getPropertyValues() { return propertyValues; } public void setPropertyValues(PropertyValues propertyValues) { this.propertyValues = propertyValues; } }
public class PropertyValues { private final List<PropertyValue> propertyValueList = new ArrayList<>(); public void addPropertyValue(PropertyValue pv) { this.propertyValueList.add(pv); } public PropertyValue[] getPropertyValues() { return this.propertyValueList.toArray(new PropertyValue[0]); } public PropertyValue getPropertyValue(String propertyName) { for (PropertyValue pv : this.propertyValueList) { if (pv.getName().equals(propertyName)) { return pv; } } return null; } }
public class PropertyValue { private final String name; private final Object value; public PropertyValue(String name, Object value) { this.name = name; this.value = value; } public String getName() { return name; } public Object getValue() { return value; } }
public abstract class AbstractAutowireCapableBean extends AbstractBeanFactory{ private InstantiationStrategy instantiationStrategy = new CglibSubclassingInstantiationStrategy(); @Override protected Object createBean(String beanName, BeanDefinition beanDefinition, Object[] args) throws BeansException { Object bean = null; try { bean = createBeanInstance(beanDefinition, beanName, args); // 给 Bean 填充属性 applyPropertyValues(beanName, bean, beanDefinition); } catch (Exception e) { throw new BeansException("Instantiation of bean failed", e); } addSingleton(beanName, bean); return bean; } /** * Bean 属性填充 */ protected void applyPropertyValues(String beanName, Object bean, BeanDefinition beanDefinition) { try { PropertyValues propertyValues = beanDefinition.getPropertyValues(); for (PropertyValue propertyValue : propertyValues.getPropertyValues()) { String name = propertyValue.getName(); Object value = propertyValue.getValue(); if (value instanceof BeanReference) { // A 依赖 B,获取 B 的实例化 BeanReference beanReference = (BeanReference) value; value = getBean(beanReference.getBeanName()); } // 属性填充 BeanUtil.setFieldValue(bean, name, value); } } catch (Exception e) { throw new BeansException("Error setting property values:" + beanName); } } protected Object createBeanInstance(BeanDefinition beanDefinition, String beanName, Object[] args) { Constructor constructorToUse = null; Class<?> beanClass = beanDefinition.getBeanClass(); Constructor<?>[] declaredConstructors = beanClass.getDeclaredConstructors(); for (Constructor ctor : declaredConstructors) { if (null != args && ctor.getParameterTypes().length == args.length) { constructorToUse = ctor; break; } } return getInstantiationStrategy().instantiate(beanDefinition, beanName, constructorToUse, args); } public InstantiationStrategy getInstantiationStrategy() { return instantiationStrategy; } public void setInstantiationStrategy(InstantiationStrategy instantiationStrategy) { this.instantiationStrategy = instantiationStrategy; } }
测试代码
@Test public void test_BeanFactory() { // 1.初始化 BeanFactory DefaultListableBeanFactory beanFactory = new DefaultListableBeanFactory(); // 2. UserDao 注册 beanFactory.registerBeanDefinition("userDao", new BeanDefinition(UserDao.class)); // 3. UserService 设置属性[uId、userDao] PropertyValues propertyValues = new PropertyValues(); propertyValues.addPropertyValue(new PropertyValue("uId", "10001")); propertyValues.addPropertyValue(new PropertyValue("userDao",new BeanReference("userDao"))); // 4. UserService 注入bean BeanDefinition beanDefinition = new BeanDefinition(UserService.class, propertyValues); beanFactory.registerBeanDefinition("userService", beanDefinition); // 5. UserService 获取bean UserService userService = (UserService) beanFactory.getBean("userService"); userService.queryUserInfo(); }
版本V5.0 设计与实现资源加载器,从Spring.xml解析和注册Bean对象
增加xml文件解析功能,从spring.xml解析跟注册bean
在XmlBeanDefinitionReader中进行xml文件解析,将解析出的beanDefinition 注册到BeanFactory中。
public abstract class AbstractBeanDefinitionReader implements BeanDefinitionReader { private final BeanDefinitionRegistry registry; private ResourceLoader resourceLoader; protected AbstractBeanDefinitionReader(BeanDefinitionRegistry registry) { this(registry, new DefaultResourceLoader()); } public AbstractBeanDefinitionReader(BeanDefinitionRegistry registry, ResourceLoader resourceLoader) { this.registry = registry; this.resourceLoader = resourceLoader; } @Override public BeanDefinitionRegistry getRegistry() { return registry; } @Override public ResourceLoader getResourceLoader() { return resourceLoader; } }
public class XmlBeanDefinitionReader extends AbstractBeanDefinitionReader { public XmlBeanDefinitionReader(BeanDefinitionRegistry registry) { super(registry); } public XmlBeanDefinitionReader(BeanDefinitionRegistry registry, ResourceLoader resourceLoader) { super(registry, resourceLoader); } @Override public void loadBeanDefinitions(Resource resource) throws BeansException { try { try (InputStream inputStream = resource.getInputStream()) { doLoadBeanDefinitions(inputStream); } } catch (IOException | ClassNotFoundException e) { throw new BeansException("IOException parsing XML document from " + resource, e); } } @Override public void loadBeanDefinitions(Resource... resources) throws BeansException { for (Resource resource : resources) { loadBeanDefinitions(resource); } } @Override public void loadBeanDefinitions(String location) throws BeansException { ResourceLoader resourceLoader = getResourceLoader(); Resource resource = resourceLoader.getResource(location); loadBeanDefinitions(resource); } protected void doLoadBeanDefinitions(InputStream inputStream) throws ClassNotFoundException { Document doc = XmlUtil.readXML(inputStream); Element root = doc.getDocumentElement(); NodeList childNodes = root.getChildNodes(); for (int i = 0; i < childNodes.getLength(); i++) { // 判断元素 if (!(childNodes.item(i) instanceof Element)) continue; // 判断对象 if (!"bean".equals(childNodes.item(i).getNodeName())) continue; // 解析标签 Element bean = (Element) childNodes.item(i); String id = bean.getAttribute("id"); String name = bean.getAttribute("name"); String className = bean.getAttribute("class"); // 获取 Class,方便获取类中的名称 Class<?> clazz = Class.forName(className); // 优先级 id > name String beanName = StrUtil.isNotEmpty(id) ? id : name; if (StrUtil.isEmpty(beanName)) { beanName = StrUtil.lowerFirst(clazz.getSimpleName()); } // 定义Bean BeanDefinition beanDefinition = new BeanDefinition(clazz); // 读取属性并填充 for (int j = 0; j < bean.getChildNodes().getLength(); j++) { if (!(bean.getChildNodes().item(j) instanceof Element)) continue; if (!"property".equals(bean.getChildNodes().item(j).getNodeName())) continue; // 解析标签:property Element property = (Element) bean.getChildNodes().item(j); String attrName = property.getAttribute("name"); String attrValue = property.getAttribute("value"); String attrRef = property.getAttribute("ref"); // 获取属性值:引入对象、值对象 Object value = StrUtil.isNotEmpty(attrRef) ? new BeanReference(attrRef) : attrValue; // 创建属性信息 PropertyValue propertyValue = new PropertyValue(attrName, value); beanDefinition.getPropertyValues().addPropertyValue(propertyValue); } if (getRegistry().containsBeanDefinition(beanName)) { throw new BeansException("Duplicate beanName[" + beanName + "] is not allowed"); } // 注册 BeanDefinition getRegistry().registerBeanDefinition(beanName, beanDefinition); } } }
测试代码
public class UserDao { private static Map<String, String> hashMap = new HashMap<>(); static { hashMap.put("1", "a"); hashMap.put("2", "b"); hashMap.put("3", "c"); } public String queryUserName(String uId) { return hashMap.get(uId); } } public class UserService { private String uId; private UserDao userDao; public String queryUserInfo() { return ("查询用户信息:" + userDao.queryUserName(uId)); } 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 void test_BeanFactory() { // 1.初始化 BeanFactory DefaultListableBeanFactory beanFactory = new DefaultListableBeanFactory(); // 2. 读取配置文件&注册Bean XmlBeanDefinitionReader reader = new XmlBeanDefinitionReader(beanFactory); reader.loadBeanDefinitions("classpath:spring.xml"); // 3. 获取Bean对象调用方法 UserService userService = beanFactory.getBean("userService", UserService.class); String result = userService.queryUserInfo(); System.out.println("测试结果:" + result); }
测试xml
<?xml version="1.0" encoding="UTF-8"?> <beans> <bean id="userDao" class="springframework.UserDao"/> <bean id="userService" class="springframework.UserService"> <property name="uId" value="1"/> <property name="userDao" ref="userDao"/> </bean> </beans>
版本V6.0 实现应用上下文,自动识别、资源加载、扩展机制。向虚拟机注册钩子,实现Bean对象的初始化和销毁方法
实现BeanFactoryPostProcess 和 BeanPostProcessor接口。
BeanFactoryPostProcess:SpringIOC容器允许BeanFactoryPostProcessor在容器实际实例化任何bean之前读取beanDefinition,并有可能修改他.并且我们还可以配置自定义的BeanFactoryPostProcessor.如果想改变bean,那么使用beanPostProcessor。
BeanPostProcessor:作用是在Bean对象在实例化和依赖注入完毕后,在显示调用初始化方法的前后添加我们自己的逻辑。
BeanFactoryPostProcess主要实现逻辑是在 beanDefinition生成后进行修改。
BeanPostProcessor 生效阶段是在bean 实例化、填充属性后,执行接口。
AbstractApplicationContext完成的任务:生成beanFactory、根据BeanFactoryPostProcess修改beanDefinition、注册实例化BeanPostProcessor对象
在AbstractAutowireCapableBean中处理init、BeanPostProcessor方法
public interface BeanFactoryPostProcessor { /** * 在所有的 BeanDefinition 加载完成后,实例化 Bean 对象之前,提供修改 BeanDefinition 属性的机制 * */ void postProcessBeanFactory(ConfigurableListableBeanFactory beanFactory) throws BeansException; }
public interface BeanPostProcessor { /** * 在 Bean 对象执行初始化方法之前,执行此方法 * * @param bean * @param beanName * @return * @throws BeansException */ Object postProcessBeforeInitialization(Object bean, String beanName) throws BeansException; /** * 在 Bean 对象执行初始化方法之后,执行此方法 * * @param bean * @param beanName * @return * @throws BeansException */ Object postProcessAfterInitialization(Object bean, String beanName) throws BeansException; }
public abstract class AbstractAutowireCapableBean extends AbstractBeanFactory implements AutowireCapableBeanFactory { private InstantiationStrategy instantiationStrategy = new CglibSubclassingInstantiationStrategy(); @Override protected Object createBean(String beanName, BeanDefinition beanDefinition, Object[] args) throws BeansException { Object bean = null; try { bean = createBeanInstance(beanDefinition, beanName, args); // 给 Bean 填充属性 applyPropertyValues(beanName, bean, beanDefinition); // 执行 Bean 的初始化方法和 BeanPostProcessor 的前置和后置处理方法 bean = initializeBean(beanName, bean, beanDefinition); } catch (Exception e) { throw new BeansException("Instantiation of bean failed", e); } addSingleton(beanName, bean); return bean; } /** * Bean 属性填充 */ protected void applyPropertyValues(String beanName, Object bean, BeanDefinition beanDefinition) { try { PropertyValues propertyValues = beanDefinition.getPropertyValues(); for (PropertyValue propertyValue : propertyValues.getPropertyValues()) { String name = propertyValue.getName(); Object value = propertyValue.getValue(); if (value instanceof BeanReference) { // A 依赖 B,获取 B 的实例化 BeanReference beanReference = (BeanReference) value; value = getBean(beanReference.getBeanName()); } // 属性填充 BeanUtil.setFieldValue(bean, name, value); } } catch (Exception e) { throw new BeansException("Error setting property values:" + beanName); } } protected Object createBeanInstance(BeanDefinition beanDefinition, String beanName, Object[] args) { Constructor constructorToUse = null; Class<?> beanClass = beanDefinition.getBeanClass(); Constructor<?>[] declaredConstructors = beanClass.getDeclaredConstructors(); for (Constructor ctor : declaredConstructors) { if (null != args && ctor.getParameterTypes().length == args.length) { constructorToUse = ctor; break; } } return getInstantiationStrategy().instantiate(beanDefinition, beanName, constructorToUse, args); } public InstantiationStrategy getInstantiationStrategy() { return instantiationStrategy; } public void setInstantiationStrategy(InstantiationStrategy instantiationStrategy) { this.instantiationStrategy = instantiationStrategy; } private Object initializeBean(String beanName, Object bean, BeanDefinition beanDefinition) { // 1. 执行 BeanPostProcessor Before 处理 Object wrappedBean = applyBeanPostProcessorsBeforeInitialization(bean, beanName); // 待完成内容:invokeInitMethods(beanName, wrappedBean, beanDefinition); invokeInitMethods(beanName, wrappedBean, beanDefinition); // 2. 执行 BeanPostProcessor After 处理 wrappedBean = applyBeanPostProcessorsAfterInitialization(wrappedBean, beanName); return wrappedBean; } private void invokeInitMethods(String beanName, Object wrappedBean, BeanDefinition beanDefinition) { } @Override public Object applyBeanPostProcessorsBeforeInitialization(Object existingBean, String beanName) throws BeansException { Object result = existingBean; for (BeanPostProcessor processor : getBeanPostProcessors()) { Object current = processor.postProcessBeforeInitialization(result, beanName); if (null == current) return result; result = current; } return result; } @Override public Object applyBeanPostProcessorsAfterInitialization(Object existingBean, String beanName) throws BeansException { Object result = existingBean; for (BeanPostProcessor processor : getBeanPostProcessors()) { Object current = processor.postProcessAfterInitialization(result, beanName); if (null == current) return result; result = current; } return result; } }
public abstract class AbstractApplicationContext extends DefaultResourceLoader implements ConfigurableApplicationContext { @Override public void refresh() throws BeansException { // 1. 创建 BeanFactory,并加载 BeanDefinition refreshBeanFactory(); // 2. 获取 BeanFactory ConfigurableListableBeanFactory beanFactory = getBeanFactory(); // 3. 在 Bean 实例化之前,执行 BeanFactoryPostProcessor (Invoke factory processors registered as beans in the context.) invokeBeanFactoryPostProcessors(beanFactory); // 4. BeanPostProcessor 需要提前于其他 Bean 对象实例化之前执行注册操作 registerBeanPostProcessors(beanFactory); // 5. 提前实例化单例Bean对象 beanFactory.preInstantiateSingletons(); } protected abstract void refreshBeanFactory() throws BeansException; protected abstract ConfigurableListableBeanFactory getBeanFactory(); private void invokeBeanFactoryPostProcessors(ConfigurableListableBeanFactory beanFactory) { Map<String, BeanFactoryPostProcessor> beanFactoryPostProcessorMap = beanFactory.getBeansOfType(BeanFactoryPostProcessor.class); for (BeanFactoryPostProcessor beanFactoryPostProcessor : beanFactoryPostProcessorMap.values()) { beanFactoryPostProcessor.postProcessBeanFactory(beanFactory); } } private void registerBeanPostProcessors(ConfigurableListableBeanFactory beanFactory) { Map<String, BeanPostProcessor> beanPostProcessorMap = beanFactory.getBeansOfType(BeanPostProcessor.class); for (BeanPostProcessor beanPostProcessor : beanPostProcessorMap.values()) { beanFactory.addBeanPostProcessor(beanPostProcessor); } } @Override public <T> Map<String, T> getBeansOfType(Class<T> type) throws BeansException { 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) throws BeansException { return getBeanFactory().getBean(name, args); } @Override public <T> T getBean(String name, Class<T> requiredType) throws BeansException { return getBeanFactory().getBean(name, requiredType); } @Override public void registerShutdownHook() { Runtime.getRuntime().addShutdownHook(new Thread(this::close)); } @Override public void close() { getBeanFactory().destroySingletons(); } }
public abstract class AbstractAutowireCapableBean extends AbstractBeanFactory implements AutowireCapableBeanFactory { private InstantiationStrategy instantiationStrategy = new CglibSubclassingInstantiationStrategy(); @Override protected Object createBean(String beanName, BeanDefinition beanDefinition, Object[] args) throws BeansException { Object bean = null; try { bean = createBeanInstance(beanDefinition, beanName, args); // 给 Bean 填充属性 applyPropertyValues(beanName, bean, beanDefinition); // 执行 Bean 的初始化方法和 BeanPostProcessor 的前置和后置处理方法 bean = initializeBean(beanName, bean, beanDefinition); } catch (Exception e) { throw new BeansException("Instantiation of bean failed", e); } addSingleton(beanName, bean); return bean; } /** * Bean 属性填充 */ protected void applyPropertyValues(String beanName, Object bean, BeanDefinition beanDefinition) { try { PropertyValues propertyValues = beanDefinition.getPropertyValues(); for (PropertyValue propertyValue : propertyValues.getPropertyValues()) { String name = propertyValue.getName(); Object value = propertyValue.getValue(); if (value instanceof BeanReference) { // A 依赖 B,获取 B 的实例化 BeanReference beanReference = (BeanReference) value; value = getBean(beanReference.getBeanName()); } // 属性填充 BeanUtil.setFieldValue(bean, name, value); } } catch (Exception e) { throw new BeansException("Error setting property values:" + beanName); } } protected Object createBeanInstance(BeanDefinition beanDefinition, String beanName, Object[] args) { Constructor constructorToUse = null; Class<?> beanClass = beanDefinition.getBeanClass(); Constructor<?>[] declaredConstructors = beanClass.getDeclaredConstructors(); for (Constructor ctor : declaredConstructors) { if (null != args && ctor.getParameterTypes().length == args.length) { constructorToUse = ctor; break; } } return getInstantiationStrategy().instantiate(beanDefinition, beanName, constructorToUse, args); } public InstantiationStrategy getInstantiationStrategy() { return instantiationStrategy; } public void setInstantiationStrategy(InstantiationStrategy instantiationStrategy) { this.instantiationStrategy = instantiationStrategy; } private Object initializeBean(String beanName, Object bean, BeanDefinition beanDefinition) { // 1. 执行 BeanPostProcessor Before 处理 Object wrappedBean = applyBeanPostProcessorsBeforeInitialization(bean, beanName); // 执行 Bean 对象的初始化方法 try { invokeInitMethods(beanName, wrappedBean, beanDefinition); } catch (Exception e) { throw new BeansException("Invocation of init method of bean[" + beanName + "] failed", e); } // 2. 执行 BeanPostProcessor After 处理 wrappedBean = applyBeanPostProcessorsAfterInitialization(wrappedBean, beanName); return wrappedBean; } private void invokeInitMethods(String beanName, Object bean, BeanDefinition beanDefinition) throws Exception { // 1. 实现接口 InitializingBean if (bean instanceof InitializingBean) { ((InitializingBean) bean).afterPropertiesSet(); } // 2. 注解配置 init-method {判断是为了避免二次执行初始化} String initMethodName = beanDefinition.getInitMethodName(); if (StrUtil.isNotEmpty(initMethodName) && !(bean instanceof InitializingBean)) { Method initMethod = beanDefinition.getBeanClass().getMethod(initMethodName); if (null == initMethod) { throw new BeansException("Could not find an init method named '" + initMethodName + "' on bean with name '" + beanName + "'"); } initMethod.invoke(bean); } } @Override public Object applyBeanPostProcessorsBeforeInitialization(Object existingBean, String beanName) throws BeansException { Object result = existingBean; for (BeanPostProcessor processor : getBeanPostProcessors()) { Object current = processor.postProcessBeforeInitialization(result, beanName); if (null == current) return result; result = current; } return result; } @Override public Object applyBeanPostProcessorsAfterInitialization(Object existingBean, String beanName) throws BeansException { Object result = existingBean; for (BeanPostProcessor processor : getBeanPostProcessors()) { Object current = processor.postProcessAfterInitialization(result, beanName); if (null == current) return result; result = current; } return result; } }
public class XmlBeanDefinitionReader extends AbstractBeanDefinitionReader { public XmlBeanDefinitionReader(BeanDefinitionRegistry registry) { super(registry); } public XmlBeanDefinitionReader(BeanDefinitionRegistry registry, ResourceLoader resourceLoader) { super(registry, resourceLoader); } @Override public void loadBeanDefinitions(Resource resource) throws BeansException { try { try (InputStream inputStream = resource.getInputStream()) { doLoadBeanDefinitions(inputStream); } } catch (IOException | ClassNotFoundException e) { throw new BeansException("IOException parsing XML document from " + resource, e); } } @Override public void loadBeanDefinitions(Resource... resources) throws BeansException { for (Resource resource : resources) { loadBeanDefinitions(resource); } } @Override public void loadBeanDefinitions(String location) throws BeansException { ResourceLoader resourceLoader = getResourceLoader(); Resource resource = resourceLoader.getResource(location); loadBeanDefinitions(resource); } @Override public void loadBeanDefinitions(String... locations) throws BeansException { for (String location : locations) { loadBeanDefinitions(location); } } protected void doLoadBeanDefinitions(InputStream inputStream) throws ClassNotFoundException { Document doc = XmlUtil.readXML(inputStream); Element root = doc.getDocumentElement(); NodeList childNodes = root.getChildNodes(); for (int i = 0; i < childNodes.getLength(); i++) { // 判断元素 if (!(childNodes.item(i) instanceof Element)) continue; // 判断对象 if (!"bean".equals(childNodes.item(i).getNodeName())) continue; // 解析标签 Element bean = (Element) childNodes.item(i); String id = bean.getAttribute("id"); String name = bean.getAttribute("name"); String className = bean.getAttribute("class"); String initMethod = bean.getAttribute("init-method"); String destroyMethodName = bean.getAttribute("destroy-method"); // 获取 Class,方便获取类中的名称 Class<?> clazz = Class.forName(className); // 优先级 id > name String beanName = StrUtil.isNotEmpty(id) ? id : name; if (StrUtil.isEmpty(beanName)) { beanName = StrUtil.lowerFirst(clazz.getSimpleName()); } // 定义Bean BeanDefinition beanDefinition = new BeanDefinition(clazz); beanDefinition.setInitMethodName(initMethod); beanDefinition.setDestroyMethodName(destroyMethodName); // 读取属性并填充 for (int j = 0; j < bean.getChildNodes().getLength(); j++) { if (!(bean.getChildNodes().item(j) instanceof Element)) continue; if (!"property".equals(bean.getChildNodes().item(j).getNodeName())) continue; // 解析标签:property Element property = (Element) bean.getChildNodes().item(j); String attrName = property.getAttribute("name"); String attrValue = property.getAttribute("value"); String attrRef = property.getAttribute("ref"); // 获取属性值:引入对象、值对象 Object value = StrUtil.isNotEmpty(attrRef) ? new BeanReference(attrRef) : attrValue; // 创建属性信息 PropertyValue propertyValue = new PropertyValue(attrName, value); beanDefinition.getPropertyValues().addPropertyValue(propertyValue); } if (getRegistry().containsBeanDefinition(beanName)) { throw new BeansException("Duplicate beanName[" + beanName + "] is not allowed"); } // 注册 BeanDefinition getRegistry().registerBeanDefinition(beanName, beanDefinition); } } }
测试代码
public class UserDao { private static Map<String, String> hashMap = new HashMap<>(); public void initDataMethod(){ System.out.println("执行:init-method"); hashMap.put("1", "a"); hashMap.put("2", "b"); hashMap.put("3", "c"); } public void destroyDataMethod(){ System.out.println("执行:destroy-method"); hashMap.clear(); } public String queryUserName(String uId) { return hashMap.get(uId); } } public class UserService implements InitializingBean, DisposableBean { private String uId; private String company; private String location; private UserDao userDao; @Override public void destroy() throws Exception { System.out.println("执行:UserService.destroy"); } @Override public void afterPropertiesSet() throws Exception { System.out.println("执行:UserService.afterPropertiesSet"); } public String queryUserInfo() { return userDao.queryUserName(uId) + "," + company + "," + location; } public String getuId() { return uId; } public void setuId(String uId) { this.uId = uId; } public String getCompany() { return company; } public void setCompany(String company) { this.company = company; } public String getLocation() { return location; } public void setLocation(String location) { this.location = location; } public UserDao getUserDao() { return userDao; } public void setUserDao(UserDao userDao) { this.userDao = userDao; } } public class MyBeanFactoryPostProcessor implements BeanFactoryPostProcessor { @Override public void postProcessBeanFactory(ConfigurableListableBeanFactory beanFactory) throws BeansException { BeanDefinition beanDefinition = beanFactory.getBeanDefinition("userService"); PropertyValues propertyValues = beanDefinition.getPropertyValues(); propertyValues.addPropertyValue(new PropertyValue("company", "改为:字节跳动")); } } public class MyBeanPostProcessor implements BeanPostProcessor { @Override public Object postProcessBeforeInitialization(Object bean, String beanName) throws BeansException { if ("userService".equals(beanName)) { UserService userService = (UserService) bean; userService.setLocation("改为:北京"); } return bean; } @Override public Object postProcessAfterInitialization(Object bean, String beanName) throws BeansException { return bean; } } public class BeanFactoryTest extends TestCase { @Test public void test_xml() { // 1.初始化 BeanFactory ClassPathXmlApplicationContext applicationContext = new ClassPathXmlApplicationContext("classpath:springPostProcessor.xml"); applicationContext.registerShutdownHook(); // 2. 获取Bean对象调用方法 UserService userService = applicationContext.getBean("userService", UserService.class); String result = userService.queryUserInfo(); System.out.println("测试结果:" + result); } @Test public void test_hook() { Runtime.getRuntime().addShutdownHook(new Thread(() -> System.out.println("close!"))); } }
测试xml
<?xml version="1.0" encoding="UTF-8"?> <beans> <bean id="userDao" class="springframework.bean.UserDao" init-method="initDataMethod" destroy-method="destroyDataMethod"/> <bean id="userService" class="springframework.bean.UserService"> <property name="uId" value="1"/> <property name="company" value="haha"/> <property name="location" value="22"/> <property name="userDao" ref="userDao"/> </bean> <bean class="springframework.common.MyBeanPostProcessor"/> <bean class="springframework.common.MyBeanFactoryPostProcessor"/> </beans>
版本V7.0 定义标记类型Aware接口,实现感知容器对象
实现Aware接口,在bean初始化的时候,根据bean classtype 设置数据。
public abstract class AbstractApplicationContext extends DefaultResourceLoader implements ConfigurableApplicationContext { @Override public void refresh() throws BeansException { // 1. 创建 BeanFactory,并加载 BeanDefinition refreshBeanFactory(); // 2. 获取 BeanFactory ConfigurableListableBeanFactory beanFactory = getBeanFactory(); // 3. 添加 ApplicationContextAwareProcessor,让继承自 ApplicationContextAware 的 Bean 对象都能感知所属的 ApplicationContext beanFactory.addBeanPostProcessor(new ApplicationContextAwareProcessor(this)); // 4. 在 Bean 实例化之前,执行 BeanFactoryPostProcessor (Invoke factory processors registered as beans in the context.) invokeBeanFactoryPostProcessors(beanFactory); // 5. BeanPostProcessor 需要提前于其他 Bean 对象实例化之前执行注册操作 registerBeanPostProcessors(beanFactory); // 6. 提前实例化单例Bean对象 beanFactory.preInstantiateSingletons(); } protected abstract void refreshBeanFactory() throws BeansException; protected abstract ConfigurableListableBeanFactory getBeanFactory(); private void invokeBeanFactoryPostProcessors(ConfigurableListableBeanFactory beanFactory) { Map<String, BeanFactoryPostProcessor> beanFactoryPostProcessorMap = beanFactory.getBeansOfType(BeanFactoryPostProcessor.class); for (BeanFactoryPostProcessor beanFactoryPostProcessor : beanFactoryPostProcessorMap.values()) { beanFactoryPostProcessor.postProcessBeanFactory(beanFactory); } } private void registerBeanPostProcessors(ConfigurableListableBeanFactory beanFactory) { Map<String, BeanPostProcessor> beanPostProcessorMap = beanFactory.getBeansOfType(BeanPostProcessor.class); for (BeanPostProcessor beanPostProcessor : beanPostProcessorMap.values()) { beanFactory.addBeanPostProcessor(beanPostProcessor); } } @Override public <T> Map<String, T> getBeansOfType(Class<T> type) throws BeansException { 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) throws BeansException { return getBeanFactory().getBean(name, args); } @Override public <T> T getBean(String name, Class<T> requiredType) throws BeansException { return getBeanFactory().getBean(name, requiredType); } @Override public void registerShutdownHook() { Runtime.getRuntime().addShutdownHook(new Thread(this::close)); } @Override public void close() { getBeanFactory().destroySingletons(); } }
public class ApplicationContextAwareProcessor implements BeanPostProcessor { private final ApplicationContext applicationContext; public ApplicationContextAwareProcessor(ApplicationContext applicationContext) { this.applicationContext = applicationContext; } @Override public Object postProcessBeforeInitialization(Object bean, String beanName) throws BeansException { if (bean instanceof ApplicationContextAware){ ((ApplicationContextAware) bean).setApplicationContext(applicationContext); } return bean; } @Override public Object postProcessAfterInitialization(Object bean, String beanName) throws BeansException { return bean; } }
public abstract class AbstractAutowireCapableBean extends AbstractBeanFactory implements AutowireCapableBeanFactory { private InstantiationStrategy instantiationStrategy = new CglibSubclassingInstantiationStrategy(); @Override protected Object createBean(String beanName, BeanDefinition beanDefinition, Object[] args) throws BeansException { Object bean = null; try { bean = createBeanInstance(beanDefinition, beanName, args); // 给 Bean 填充属性 applyPropertyValues(beanName, bean, beanDefinition); // 执行 Bean 的初始化方法和 BeanPostProcessor 的前置和后置处理方法 bean = initializeBean(beanName, bean, beanDefinition); } catch (Exception e) { throw new BeansException("Instantiation of bean failed", e); } addSingleton(beanName, bean); return bean; } /** * Bean 属性填充 */ protected void applyPropertyValues(String beanName, Object bean, BeanDefinition beanDefinition) { try { PropertyValues propertyValues = beanDefinition.getPropertyValues(); for (PropertyValue propertyValue : propertyValues.getPropertyValues()) { String name = propertyValue.getName(); Object value = propertyValue.getValue(); if (value instanceof BeanReference) { // A 依赖 B,获取 B 的实例化 BeanReference beanReference = (BeanReference) value; value = getBean(beanReference.getBeanName()); } // 属性填充 BeanUtil.setFieldValue(bean, name, value); } } catch (Exception e) { throw new BeansException("Error setting property values:" + beanName); } } protected Object createBeanInstance(BeanDefinition beanDefinition, String beanName, Object[] args) { Constructor constructorToUse = null; Class<?> beanClass = beanDefinition.getBeanClass(); Constructor<?>[] declaredConstructors = beanClass.getDeclaredConstructors(); for (Constructor ctor : declaredConstructors) { if (null != args && ctor.getParameterTypes().length == args.length) { constructorToUse = ctor; break; } } return getInstantiationStrategy().instantiate(beanDefinition, beanName, constructorToUse, args); } public InstantiationStrategy getInstantiationStrategy() { return instantiationStrategy; } public void setInstantiationStrategy(InstantiationStrategy instantiationStrategy) { this.instantiationStrategy = instantiationStrategy; } private Object initializeBean(String beanName, Object bean, BeanDefinition beanDefinition) { // invokeAwareMethods if (bean instanceof Aware) { if (bean instanceof BeanFactoryAware) { ((BeanFactoryAware) bean).setBeanFactory(this); } if (bean instanceof BeanClassLoaderAware){ ((BeanClassLoaderAware) bean).setBeanClassLoader(getBeanClassLoader()); } if (bean instanceof BeanNameAware) { ((BeanNameAware) bean).setBeanName(beanName); } } // 1. 执行 BeanPostProcessor Before 处理 Object wrappedBean = applyBeanPostProcessorsBeforeInitialization(bean, beanName); // 执行 Bean 对象的初始化方法 try { invokeInitMethods(beanName, wrappedBean, beanDefinition); } catch (Exception e) { throw new BeansException("Invocation of init method of bean[" + beanName + "] failed", e); } // 2. 执行 BeanPostProcessor After 处理 wrappedBean = applyBeanPostProcessorsAfterInitialization(wrappedBean, beanName); return wrappedBean; } private void invokeInitMethods(String beanName, Object bean, BeanDefinition beanDefinition) throws Exception { // 1. 实现接口 InitializingBean if (bean instanceof InitializingBean) { ((InitializingBean) bean).afterPropertiesSet(); } // 2. 注解配置 init-method {判断是为了避免二次执行初始化} String initMethodName = beanDefinition.getInitMethodName(); if (StrUtil.isNotEmpty(initMethodName) && !(bean instanceof InitializingBean)) { Method initMethod = beanDefinition.getBeanClass().getMethod(initMethodName); if (null == initMethod) { throw new BeansException("Could not find an init method named '" + initMethodName + "' on bean with name '" + beanName + "'"); } initMethod.invoke(bean); } } @Override public Object applyBeanPostProcessorsBeforeInitialization(Object existingBean, String beanName) throws BeansException { Object result = existingBean; for (BeanPostProcessor processor : getBeanPostProcessors()) { Object current = processor.postProcessBeforeInitialization(result, beanName); if (null == current) return result; result = current; } return result; } @Override public Object applyBeanPostProcessorsAfterInitialization(Object existingBean, String beanName) throws BeansException { Object result = existingBean; for (BeanPostProcessor processor : getBeanPostProcessors()) { Object current = processor.postProcessAfterInitialization(result, beanName); if (null == current) return result; result = current; } return result; } }
测试代码
public class UserService implements BeanNameAware, BeanClassLoaderAware, ApplicationContextAware, BeanFactoryAware { private ApplicationContext applicationContext; private BeanFactory beanFactory; private String uId; private String company; private String location; private UserDao userDao; @Override public void setBeanFactory(BeanFactory beanFactory) throws BeansException { this.beanFactory = beanFactory; } @Override public void setApplicationContext(ApplicationContext applicationContext) throws BeansException { this.applicationContext = applicationContext; } @Override public void setBeanName(String name) { System.out.println("Bean Name is:" + name); } @Override public void setBeanClassLoader(ClassLoader classLoader) { System.out.println("ClassLoader:" + classLoader); } public String queryUserInfo() { return userDao.queryUserName(uId) + "," + company + "," + location; } public String getuId() { return uId; } public void setuId(String uId) { this.uId = uId; } public String getCompany() { return company; } public void setCompany(String company) { this.company = company; } public String getLocation() { return location; } public void setLocation(String location) { this.location = location; } public UserDao getUserDao() { return userDao; } public void setUserDao(UserDao userDao) { this.userDao = userDao; } public ApplicationContext getApplicationContext() { return applicationContext; } public BeanFactory getBeanFactory() { return beanFactory; } } public class BeanFactoryTest extends TestCase { @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); String result = userService.queryUserInfo(); System.out.println("测试结果:" + result); System.out.println("ApplicationContextAware:"+userService.getApplicationContext()); System.out.println("BeanFactoryAware:"+userService.getBeanFactory()); } }
ps:
在具体的接口实现过程中你可以看到,一部分(BeanFactoryAware、BeanClassLoaderAware、BeanNameAware)在 factory 的 support 文件夹下,另外 ApplicationContextAware 是在 context 的 support 中,这是因为不同的内容获取需要在不同的包下提供。所以,在 AbstractApplicationContext 的具体实现中会用到向 beanFactory 添加 BeanPostProcessor 内容的 ApplicationContextAwareProcessor
操作,最后由 AbstractAutowireCapableBeanFactory 创建 createBean 时处理相应的调用操作。
版本V8.0 关于Bean对象作用域以及FactoryBean的实现和使用
FactoryBean:是实现了 FactoryBean<T> 接⼝的Bean,根据该Bean的ID从BeanFactory中获取的实际上是FactoryBean的getObject()返回的对象,⽽不是FactoryBean本身,如果要获取FactoryBean对象,请在id前⾯加⼀个&符号来获取。
思路:在beanDefinition中增加scope属性,决定是否使用单例缓存; getBean()时如果发现bean是FactoryBean,使用getObject(),替代createBean();
public abstract class AbstractBeanFactory extends FactoryBeanRegistrySupport implements ConfigurableBeanFactory { private ClassLoader beanClassLoader = ClassUtils.getDefaultClassLoader(); private final List<BeanPostProcessor> beanPostProcessors = new ArrayList<>(); @Override public Object getBean(String name) throws BeansException { return doGetBean(name, null); } @Override public Object getBean(String name, Object... args) throws BeansException { return doGetBean(name, args); } @Override public <T> T getBean(String name, Class<T> requiredType) throws BeansException { return (T) getBean(name); } protected <T> T doGetBean(final String name, final Object[] args) { Object sharedInstance = getSingleton(name); if (sharedInstance != null) { // 如果是 FactoryBean,则需要调用 FactoryBean#getObject return (T) getObjectForBeanInstance(sharedInstance, name); } BeanDefinition beanDefinition = getBeanDefinition(name); Object bean = createBean(name, beanDefinition, args); return (T) getObjectForBeanInstance(bean, name); } private Object getObjectForBeanInstance(Object beanInstance, String beanName) { if (!(beanInstance instanceof FactoryBean)) { return beanInstance; } Object object = getCachedObjectForFactoryBean(beanName); if (object == null) { FactoryBean<?> factoryBean = (FactoryBean<?>) beanInstance; object = getObjectFromFactoryBean(factoryBean, beanName); } return object; } protected abstract BeanDefinition getBeanDefinition(String beanName) throws BeansException; protected abstract Object createBean(String beanName, BeanDefinition beanDefinition, Object[] args) throws BeansException; @Override public void addBeanPostProcessor(BeanPostProcessor beanPostProcessor){ this.beanPostProcessors.remove(beanPostProcessor); this.beanPostProcessors.add(beanPostProcessor); } public List<BeanPostProcessor> getBeanPostProcessors() { return this.beanPostProcessors; } public ClassLoader getBeanClassLoader() { return this.beanClassLoader; } }
public abstract class FactoryBeanRegistrySupport extends DefaultSingletonBeanRegistry { /** * Cache of singleton objects created by FactoryBeans: FactoryBean name --> object */ private final Map<String, Object> factoryBeanObjectCache = new ConcurrentHashMap<String, Object>(); protected Object getCachedObjectForFactoryBean(String beanName) { Object object = this.factoryBeanObjectCache.get(beanName); return (object != NULL_OBJECT ? object : null); } protected Object getObjectFromFactoryBean(FactoryBean factory, String beanName) { if (factory.isSingleton()) { Object object = this.factoryBeanObjectCache.get(beanName); if (object == null) { object = doGetObjectFromFactoryBean(factory, beanName); this.factoryBeanObjectCache.put(beanName, (object != null ? object : NULL_OBJECT)); } return (object != NULL_OBJECT ? object : null); } else { return doGetObjectFromFactoryBean(factory, beanName); } } private Object doGetObjectFromFactoryBean(final FactoryBean factory, final String beanName){ try { return factory.getObject(); } catch (Exception e) { throw new BeansException("FactoryBean threw exception on object[" + beanName + "] creation", e); } } }
public abstract class AbstractAutowireCapableBean extends AbstractBeanFactory implements AutowireCapableBeanFactory { private InstantiationStrategy instantiationStrategy = new SimpleInstantiationStrategy(); @Override protected Object createBean(String beanName, BeanDefinition beanDefinition, Object[] args) throws BeansException { Object bean = null; try { bean = createBeanInstance(beanDefinition, beanName, args); // 给 Bean 填充属性 applyPropertyValues(beanName, bean, beanDefinition); // 执行 Bean 的初始化方法和 BeanPostProcessor 的前置和后置处理方法 bean = initializeBean(beanName, bean, beanDefinition); } catch (Exception e) { throw new BeansException("Instantiation of bean failed", e); } // 注册实现了 DisposableBean 接口的 Bean 对象 registerDisposableBeanIfNecessary(beanName, bean, beanDefinition); // 判断 SCOPE_SINGLETON、SCOPE_PROTOTYPE if (beanDefinition.isSingleton()) { addSingleton(beanName, bean); } return bean; } }
版本V9.0 基于观察者实现,容器事件和事件监听器
在整个功能实现过程中,仍然需要在面向用户的应用上下文 AbstractApplicationContext
中添加相关事件内容,包括:初始化事件发布者、注册事件监听器、发布容器刷新完成事件。
使用观察者模式定义事件类、监听类、发布类,同时还需要完成一个广播器的功能,接收到事件推送时进行分析处理符合监听事件接受者感兴趣的事件,也就是使用 isAssignableFrom 进行判断。
理解event包下消息发布、监听机制。在AbstractApplicationContext.refresh()中实现监听机制。
public abstract class AbstractApplicationContext extends DefaultResourceLoader implements ConfigurableApplicationContext { public static final String APPLICATION_EVENT_MULTICASTER_BEAN_NAME = "applicationEventMulticaster"; private ApplicationEventMulticaster applicationEventMulticaster; @Override public void refresh() throws BeansException { // 1. 创建 BeanFactory,并加载 BeanDefinition refreshBeanFactory(); // 2. 获取 BeanFactory ConfigurableListableBeanFactory beanFactory = getBeanFactory(); // 3. 添加 ApplicationContextAwareProcessor,让继承自 ApplicationContextAware 的 Bean 对象都能感知所属的 ApplicationContext beanFactory.addBeanPostProcessor(new ApplicationContextAwareProcessor(this)); // 4. 在 Bean 实例化之前,执行 BeanFactoryPostProcessor (Invoke factory processors registered as beans in the context.) invokeBeanFactoryPostProcessors(beanFactory); // 5. BeanPostProcessor 需要提前于其他 Bean 对象实例化之前执行注册操作 registerBeanPostProcessors(beanFactory); // 6. 初始化事件发布者 initApplicationEventMulticaster(); // 7. 注册事件监听器 registerListeners(); // 8. 提前实例化单例Bean对象 beanFactory.preInstantiateSingletons(); // 9. 发布容器刷新完成事件 finishRefresh(); } protected abstract void refreshBeanFactory() throws BeansException; protected abstract ConfigurableListableBeanFactory getBeanFactory(); private void invokeBeanFactoryPostProcessors(ConfigurableListableBeanFactory beanFactory) { Map<String, BeanFactoryPostProcessor> beanFactoryPostProcessorMap = beanFactory.getBeansOfType(BeanFactoryPostProcessor.class); for (BeanFactoryPostProcessor beanFactoryPostProcessor : beanFactoryPostProcessorMap.values()) { beanFactoryPostProcessor.postProcessBeanFactory(beanFactory); } } private void registerBeanPostProcessors(ConfigurableListableBeanFactory beanFactory) { Map<String, BeanPostProcessor> beanPostProcessorMap = beanFactory.getBeansOfType(BeanPostProcessor.class); for (BeanPostProcessor beanPostProcessor : beanPostProcessorMap.values()) { beanFactory.addBeanPostProcessor(beanPostProcessor); } } @Override public <T> Map<String, T> getBeansOfType(Class<T> type) throws BeansException { 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) throws BeansException { return getBeanFactory().getBean(name, args); } @Override public <T> T getBean(String name, Class<T> requiredType) throws BeansException { return getBeanFactory().getBean(name, requiredType); } @Override public void registerShutdownHook() { Runtime.getRuntime().addShutdownHook(new Thread(this::close)); } @Override public void close() { getBeanFactory().destroySingletons(); } private void initApplicationEventMulticaster() { ConfigurableListableBeanFactory beanFactory = getBeanFactory(); applicationEventMulticaster = new SimpleApplicationEventMulticaster(beanFactory); beanFactory.registerSingleton(APPLICATION_EVENT_MULTICASTER_BEAN_NAME, applicationEventMulticaster); } private void registerListeners() { Collection<ApplicationListener> applicationListeners = getBeansOfType(ApplicationListener.class).values(); for (ApplicationListener listener : applicationListeners) { applicationEventMulticaster.addApplicationListener(listener); } } private void finishRefresh() { publishEvent(new ContextRefreshedEvent(this)); } @Override public void publishEvent(ApplicationEvent event) { applicationEventMulticaster.multicastEvent(event); } }
public abstract class AbstractApplicationEventMulticaster implements ApplicationEventMulticaster, BeanFactoryAware { public final Set<ApplicationListener<ApplicationEvent>> applicationListeners = new LinkedHashSet<>(); private BeanFactory beanFactory; @Override public void addApplicationListener(ApplicationListener<?> listener) { applicationListeners.add((ApplicationListener<ApplicationEvent>) listener); } @Override public void removeApplicationListener(ApplicationListener<?> listener) { applicationListeners.remove(listener); } @Override public final void setBeanFactory(BeanFactory beanFactory) { this.beanFactory = beanFactory; } /** * Return a Collection of ApplicationListeners matching the given * event type. Non-matching listeners get excluded early. * @param event the event to be propagated. Allows for excluding * non-matching listeners early, based on cached matching information. * @return a Collection of ApplicationListeners * @see cn.bugstack.springframework.context.ApplicationListener */ protected Collection<ApplicationListener> getApplicationListeners(ApplicationEvent event) { LinkedList<ApplicationListener> allListeners = new LinkedList<ApplicationListener>(); for (ApplicationListener<ApplicationEvent> listener : applicationListeners) { if (supportsEvent(listener, event)) allListeners.add(listener); } return allListeners; } /** * 监听器是否对该事件感兴趣 */ protected boolean supportsEvent(ApplicationListener<ApplicationEvent> applicationListener, ApplicationEvent event) { Class<? extends ApplicationListener> listenerClass = applicationListener.getClass(); // 按照 CglibSubclassingInstantiationStrategy、SimpleInstantiationStrategy 不同的实例化类型,需要判断后获取目标 class Class<?> targetClass = ClassUtils.isCglibProxyClass(listenerClass) ? listenerClass.getSuperclass() : listenerClass; Type genericInterface = targetClass.getGenericInterfaces()[0]; Type actualTypeArgument = ((ParameterizedType) genericInterface).getActualTypeArguments()[0]; String className = actualTypeArgument.getTypeName(); Class<?> eventClassName; try { eventClassName = Class.forName(className); } catch (ClassNotFoundException e) { throw new BeansException("wrong event class name: " + className); } // 判定此 eventClassName 对象所表示的类或接口与指定的 event.getClass() 参数所表示的类或接口是否相同,或是否是其超类或超接口。 // isAssignableFrom是用来判断子类和父类的关系的,或者接口的实现类和接口的关系的,默认所有的类的终极父类都是Object。如果A.isAssignableFrom(B)结果是true,证明B可以转换成为A,也就是A可以由B转换而来。 return eventClassName.isAssignableFrom(event.getClass()); } }
public class ApplicationContextEvent extends ApplicationEvent { /** * Constructs a prototypical Event. * * @param source The object on which the Event initially occurred. * @throws IllegalArgumentException if source is null. */ public ApplicationContextEvent(Object source) { super(source); } /** * Get the <code>ApplicationContext</code> that the event was raised for. */ public final ApplicationContext getApplicationContext() { return (ApplicationContext) getSource(); } }
public interface ApplicationEventMulticaster { /** * Add a listener to be notified of all events. * @param listener the listener to add */ void addApplicationListener(ApplicationListener<?> listener); /** * Remove a listener from the notification list. * @param listener the listener to remove */ void removeApplicationListener(ApplicationListener<?> listener); /** * Multicast the given application event to appropriate listeners. * @param event the event to multicast */ void multicastEvent(ApplicationEvent event); }
public class ContextClosedEvent extends ApplicationContextEvent{ /** * Constructs a prototypical Event. * * @param source The object on which the Event initially occurred. * @throws IllegalArgumentException if source is null. */ public ContextClosedEvent(Object source) { super(source); } }
public class ContextRefreshedEvent extends ApplicationContextEvent{ /** * Constructs a prototypical Event. * * @param source The object on which the Event initially occurred. * @throws IllegalArgumentException if source is null. */ public ContextRefreshedEvent(Object source) { super(source); } }
public class SimpleApplicationEventMulticaster extends AbstractApplicationEventMulticaster { public SimpleApplicationEventMulticaster(BeanFactory beanFactory) { setBeanFactory(beanFactory); } @SuppressWarnings("unchecked") @Override public void multicastEvent(final ApplicationEvent event) { for (final ApplicationListener listener : getApplicationListeners(event)) { listener.onApplicationEvent(event); } } }
测试代码
public class ContextClosedEventListener implements ApplicationListener<ContextClosedEvent> { @Override public void onApplicationEvent(ContextClosedEvent event) { System.out.println("关闭事件:" + this.getClass().getName()); } } public class ContextRefreshedEventListener implements ApplicationListener<ContextRefreshedEvent> { @Override public void onApplicationEvent(ContextRefreshedEvent event) { System.out.println("刷新事件:" + this.getClass().getName()); } } public class CustomEvent extends ApplicationContextEvent { private Long id; private String message; /** * Constructs a prototypical Event. * * @param source The object on which the Event initially occurred. * @throws IllegalArgumentException if source is null. */ public CustomEvent(Object source, Long id, String message) { super(source); this.id = id; this.message = message; } public Long getId() { return id; } public void setId(Long id) { this.id = id; } public String getMessage() { return message; } public void setMessage(String message) { this.message = message; } } public class CustomEventListener implements ApplicationListener<CustomEvent> { @Override public void onApplicationEvent(CustomEvent event) { System.out.println("收到:" + event.getSource() + "消息;时间:" + new Date()); System.out.println("消息:" + event.getId() + ":" + event.getMessage()); } } 测试方法 @Test public void test_event() { ClassPathXmlApplicationContext applicationContext = new ClassPathXmlApplicationContext("classpath:spring1.xml"); applicationContext.publishEvent(new CustomEvent(applicationContext, 1L, "成功了!")); applicationContext.registerShutdownHook(); } }
<?xml version="1.0" encoding="UTF-8"?> <beans> <bean class="springframework.event.ContextRefreshedEventListener"/> <bean class="springframework.event.CustomEventListener"/> <bean class="springframework.event.ContextClosedEventListener"/> </beans>
刷新事件:springframework.event.ContextRefreshedEventListener
收到:springframework.context.support.ClassPathXmlApplicationContext@6996db8消息;时间:Tue Mar 07 20:05:24 CST 2023
消息:1019129009086763:成功了!
版本V10.0 于JDK和Cglib动态代理,实现AOP核心功能
将复杂的代理实现过程 封装到AdviseSupport
public class AspectJExpressionPointcut implements Pointcut, ClassFilter, MethodMatcher { private static final Set<PointcutPrimitive> SUPPORTED_PRIMITIVES = new HashSet<PointcutPrimitive>(); static { SUPPORTED_PRIMITIVES.add(PointcutPrimitive.EXECUTION); } private final PointcutExpression pointcutExpression; public AspectJExpressionPointcut(String expression) { PointcutParser pointcutParser = PointcutParser.getPointcutParserSupportingSpecifiedPrimitivesAndUsingSpecifiedClassLoaderForResolution(SUPPORTED_PRIMITIVES, this.getClass().getClassLoader()); pointcutExpression = pointcutParser.parsePointcutExpression(expression); } @Override public boolean matches(Class<?> clazz) { return pointcutExpression.couldMatchJoinPointsInType(clazz); } @Override public boolean matches(Method method, Class<?> targetClass) { return pointcutExpression.matchesMethodExecution(method).alwaysMatches(); } @Override public ClassFilter getClassFilter() { return this; } @Override public MethodMatcher getMethodMatcher() { return this; } }
public interface AopProxy { Object getProxy(); }
public class Cglib2AopProxy implements AopProxy { private final AdvisedSupport advised; public Cglib2AopProxy(AdvisedSupport advised) { this.advised = advised; } @Override public Object getProxy() { Enhancer enhancer = new Enhancer(); enhancer.setSuperclass(advised.getTargetSource().getTarget().getClass()); enhancer.setInterfaces(advised.getTargetSource().getTargetClass()); enhancer.setCallback(new DynamicAdvisedInterceptor(advised)); return enhancer.create(); } private static class DynamicAdvisedInterceptor implements MethodInterceptor { private final AdvisedSupport advised; public DynamicAdvisedInterceptor(AdvisedSupport advised) { this.advised = advised; } @Override public Object intercept(Object o, Method method, Object[] objects, MethodProxy methodProxy) throws Throwable { CglibMethodInvocation methodInvocation = new CglibMethodInvocation(advised.getTargetSource().getTarget(), method, objects, methodProxy); if (advised.getMethodMatcher().matches(method, advised.getTargetSource().getTarget().getClass())) { return advised.getMethodInterceptor().invoke(methodInvocation); } return methodInvocation.proceed(); } } private static class CglibMethodInvocation extends ReflectiveMethodInvocation { private final MethodProxy methodProxy; public CglibMethodInvocation(Object target, Method method, Object[] arguments, MethodProxy methodProxy) { super(target, method, arguments); this.methodProxy = methodProxy; } @Override public Object proceed() throws Throwable { return this.methodProxy.invoke(this.target, this.arguments); } } }
public class JdkDynamicAopProxy implements AopProxy, InvocationHandler { private final AdvisedSupport advised; public JdkDynamicAopProxy(AdvisedSupport advised) { this.advised = advised; } @Override public Object getProxy() { return Proxy.newProxyInstance(Thread.currentThread().getContextClassLoader(), advised.getTargetSource().getTargetClass(), this); } @Override public Object invoke(Object proxy, Method method, Object[] args) throws Throwable { if (advised.getMethodMatcher().matches(method, advised.getTargetSource().getTarget().getClass())) { MethodInterceptor methodInterceptor = advised.getMethodInterceptor(); return methodInterceptor.invoke(new ReflectiveMethodInvocation(advised.getTargetSource().getTarget(), method, args)); } return method.invoke(advised.getTargetSource().getTarget(), args); } }
public class ReflectiveMethodInvocation implements MethodInvocation { // 目标对象 protected final Object target; // 方法 protected final Method method; // 入参 protected final Object[] arguments; public ReflectiveMethodInvocation(Object target, Method method, Object[] arguments) { this.target = target; this.method = method; this.arguments = arguments; } @Override public Method getMethod() { return method; } @Override public Object[] getArguments() { return arguments; } @Override public Object proceed() throws Throwable { return method.invoke(target, arguments); } @Override public Object getThis() { return target; } @Override public AccessibleObject getStaticPart() { return method; } }
public class AdvisedSupport { // 被代理的目标对象 private TargetSource targetSource; // 方法拦截器 private MethodInterceptor methodInterceptor; // 方法匹配器(检查目标方法是否符合通知条件) private MethodMatcher methodMatcher; public TargetSource getTargetSource() { return targetSource; } public void setTargetSource(TargetSource targetSource) { this.targetSource = targetSource; } public MethodInterceptor getMethodInterceptor() { return methodInterceptor; } public void setMethodInterceptor(MethodInterceptor methodInterceptor) { this.methodInterceptor = methodInterceptor; } public MethodMatcher getMethodMatcher() { return methodMatcher; } public void setMethodMatcher(MethodMatcher methodMatcher) { this.methodMatcher = methodMatcher; } }
public interface ClassFilter { /** * Should the pointcut apply to the given interface or target class? * @param clazz the candidate target class * @return whether the advice should apply to the given target class */ boolean matches(Class<?> clazz); } public interface MethodMatcher { /** * Perform static checking whether the given method matches. If this * @return whether or not this method matches statically */ boolean matches(Method method, Class<?> targetClass); } public interface Pointcut { /** * Return the ClassFilter for this pointcut. * * @return the ClassFilter (never <code>null</code>) */ ClassFilter getClassFilter(); /** * Return the MethodMatcher for this pointcut. * * @return the MethodMatcher (never <code>null</code>) */ MethodMatcher getMethodMatcher(); }
public class TargetSource { private final Object target; public TargetSource(Object target) { this.target = target; } /** * Return the type of targets returned by this {@link TargetSource}. * <p>Can return <code>null</code>, although certain usages of a * <code>TargetSource</code> might just work with a predetermined * target class. * @return the type of targets returned by this {@link TargetSource} */ public Class<?>[] getTargetClass(){ return this.target.getClass().getInterfaces(); } /** * Return a target instance. Invoked immediately before the * AOP framework calls the "target" of an AOP method invocation. * @return the target object, which contains the joinpoint * @throws Exception if the target object can't be resolved */ public Object getTarget(){ return this.target; } }
测试
@Test public void test_proxy_class() { IUserService userService = (IUserService) Proxy.newProxyInstance(Thread.currentThread().getContextClassLoader(), new Class[]{IUserService.class}, (proxy, method, args) -> "你被代理了!"); String result = userService.queryUserInfo(); System.out.println("测试结果:" + result); } @Test public void test_proxy_method() { // 目标对象(可以替换成任何的目标对象) Object targetObj = new UserService(); // AOP 代理 IUserService proxy = (IUserService) Proxy.newProxyInstance(Thread.currentThread().getContextClassLoader(), targetObj.getClass().getInterfaces(), new InvocationHandler() { // 方法匹配器 MethodMatcher methodMatcher = new AspectJExpressionPointcut("execution(* springframework.bean.IUserService.*(..))"); @Override public Object invoke(Object proxy, Method method, Object[] args) throws Throwable { if (methodMatcher.matches(method, targetObj.getClass())) { // 方法拦截器 MethodInterceptor methodInterceptor = invocation -> { long start = System.currentTimeMillis(); try { return invocation.proceed(); } finally { System.out.println("监控 - Begin By AOP"); System.out.println("方法名称:" + invocation.getMethod().getName()); System.out.println("方法耗时:" + (System.currentTimeMillis() - start) + "ms"); System.out.println("监控 - End\r\n"); } }; // 反射调用 return methodInterceptor.invoke(new ReflectiveMethodInvocation(targetObj, method, args)); } return method.invoke(targetObj, args); } }); String result = proxy.queryUserInfo(); System.out.println("测试结果:" + result); } @Test public void test_dynamic() { // 目标对象 IUserService userService = new UserService(); // 组装代理信息 AdvisedSupport advisedSupport = new AdvisedSupport(); advisedSupport.setTargetSource(new TargetSource(userService)); advisedSupport.setMethodInterceptor(new UserServiceInterceptor()); advisedSupport.setMethodMatcher(new AspectJExpressionPointcut("execution(* springframework.bean.IUserService.*(..))")); // 代理对象(JdkDynamicAopProxy) IUserService proxy_jdk = (IUserService) new JdkDynamicAopProxy(advisedSupport).getProxy(); // 测试调用 System.out.println("测试结果:" + proxy_jdk.queryUserInfo()); // 代理对象(Cglib2AopProxy) IUserService proxy_cglib = (IUserService) new Cglib2AopProxy(advisedSupport).getProxy(); // 测试调用 System.out.println("测试结果:" + proxy_cglib.register("花花")); }
版本V11.0 把AOP动态代理,融入到Bean的生命周期
利用V10版本的AOP能力,
在createBean时,在InstantiationAwareBeanPostProcessor中根据AspectJExpressionPointcutAdvisor判断是否需要代理目标类,如需代理,则返回代理对象。
public abstract class AbstractAutowireCapableBeanFactory extends AbstractBeanFactory implements AutowireCapableBeanFactory { private InstantiationStrategy instantiationStrategy = new CglibSubclassingInstantiationStrategy(); @Override protected Object createBean(String beanName, BeanDefinition beanDefinition, Object[] args) throws BeansException { Object bean = null; try { // 判断是否返回代理 Bean 对象 bean = resolveBeforeInstantiation(beanName, beanDefinition); if (null != bean) { return bean; } // 实例化 Bean bean = createBeanInstance(beanDefinition, beanName, args); // 给 Bean 填充属性 applyPropertyValues(beanName, bean, beanDefinition); // 执行 Bean 的初始化方法和 BeanPostProcessor 的前置和后置处理方法 bean = initializeBean(beanName, bean, beanDefinition); } catch (Exception e) { throw new BeansException("Instantiation of bean failed", e); } // 注册实现了 DisposableBean 接口的 Bean 对象 registerDisposableBeanIfNecessary(beanName, bean, beanDefinition); // 判断 SCOPE_SINGLETON、SCOPE_PROTOTYPE if (beanDefinition.isSingleton()) { registerSingleton(beanName, bean); } return bean; } protected Object resolveBeforeInstantiation(String beanName, BeanDefinition beanDefinition) { Object bean = applyBeanPostProcessorsBeforeInstantiation(beanDefinition.getBeanClass(), beanName); if (null != bean) { bean = applyBeanPostProcessorsAfterInitialization(bean, beanName); } return bean; } protected Object applyBeanPostProcessorsBeforeInstantiation(Class<?> beanClass, String beanName) { for (BeanPostProcessor beanPostProcessor : getBeanPostProcessors()) { if (beanPostProcessor instanceof InstantiationAwareBeanPostProcessor) { Object result = ((InstantiationAwareBeanPostProcessor) beanPostProcessor).postProcessBeforeInstantiation(beanClass, beanName); if (null != result) return result; } } return null; } protected void registerDisposableBeanIfNecessary(String beanName, Object bean, BeanDefinition beanDefinition) { // 非 Singleton 类型的 Bean 不执行销毁方法 if (!beanDefinition.isSingleton()) return; if (bean instanceof DisposableBean || StrUtil.isNotEmpty(beanDefinition.getDestroyMethodName())) { registerDisposableBean(beanName, new DisposableBeanAdapter(bean, beanName, beanDefinition)); } } protected Object createBeanInstance(BeanDefinition beanDefinition, String beanName, Object[] args) { Constructor constructorToUse = null; Class<?> beanClass = beanDefinition.getBeanClass(); Constructor<?>[] declaredConstructors = beanClass.getDeclaredConstructors(); for (Constructor ctor : declaredConstructors) { if (null != args && ctor.getParameterTypes().length == args.length) { constructorToUse = ctor; break; } } return getInstantiationStrategy().instantiate(beanDefinition, beanName, constructorToUse, args); } /** * Bean 属性填充 */ protected void applyPropertyValues(String beanName, Object bean, BeanDefinition beanDefinition) { try { PropertyValues propertyValues = beanDefinition.getPropertyValues(); for (PropertyValue propertyValue : propertyValues.getPropertyValues()) { String name = propertyValue.getName(); Object value = propertyValue.getValue(); if (value instanceof BeanReference) { // A 依赖 B,获取 B 的实例化 BeanReference beanReference = (BeanReference) value; value = getBean(beanReference.getBeanName()); } // 属性填充 BeanUtil.setFieldValue(bean, name, value); } } catch (Exception e) { throw new BeansException("Error setting property values:" + beanName); } } public InstantiationStrategy getInstantiationStrategy() { return instantiationStrategy; } public void setInstantiationStrategy(InstantiationStrategy instantiationStrategy) { this.instantiationStrategy = instantiationStrategy; } private Object initializeBean(String beanName, Object bean, BeanDefinition beanDefinition) { // invokeAwareMethods if (bean instanceof Aware) { if (bean instanceof BeanFactoryAware) { ((BeanFactoryAware) bean).setBeanFactory(this); } if (bean instanceof BeanClassLoaderAware) { ((BeanClassLoaderAware) bean).setBeanClassLoader(getBeanClassLoader()); } if (bean instanceof BeanNameAware) { ((BeanNameAware) bean).setBeanName(beanName); } } // 1. 执行 BeanPostProcessor Before 处理 Object wrappedBean = applyBeanPostProcessorsBeforeInitialization(bean, beanName); // 执行 Bean 对象的初始化方法 try { invokeInitMethods(beanName, wrappedBean, beanDefinition); } catch (Exception e) { throw new BeansException("Invocation of init method of bean[" + beanName + "] failed", e); } // 2. 执行 BeanPostProcessor After 处理 wrappedBean = applyBeanPostProcessorsAfterInitialization(wrappedBean, beanName); return wrappedBean; } private void invokeInitMethods(String beanName, Object bean, BeanDefinition beanDefinition) throws Exception { // 1. 实现接口 InitializingBean if (bean instanceof InitializingBean) { ((InitializingBean) bean).afterPropertiesSet(); } // 2. 注解配置 init-method {判断是为了避免二次执行销毁} String initMethodName = beanDefinition.getInitMethodName(); if (StrUtil.isNotEmpty(initMethodName)) { Method initMethod = beanDefinition.getBeanClass().getMethod(initMethodName); if (null == initMethod) { throw new BeansException("Could not find an init method named '" + initMethodName + "' on bean with name '" + beanName + "'"); } initMethod.invoke(bean); } } @Override public Object applyBeanPostProcessorsBeforeInitialization(Object existingBean, String beanName) throws BeansException { Object result = existingBean; for (BeanPostProcessor processor : getBeanPostProcessors()) { Object current = processor.postProcessBeforeInitialization(result, beanName); if (null == current) return result; result = current; } return result; } @Override public Object applyBeanPostProcessorsAfterInitialization(Object existingBean, String beanName) throws BeansException { Object result = existingBean; for (BeanPostProcessor processor : getBeanPostProcessors()) { Object current = processor.postProcessAfterInitialization(result, beanName); if (null == current) return result; result = current; } return result; } }
public interface InstantiationAwareBeanPostProcessor extends BeanPostProcessor { /** * Apply this BeanPostProcessor <i>before the target bean gets instantiated</i>. * The returned bean object may be a proxy to use instead of the target bean, * effectively suppressing default instantiation of the target bean. * * 在 Bean 对象执行初始化方法之前,执行此方法 * * @param beanClass * @param beanName * @return * @throws BeansException */ Object postProcessBeforeInstantiation(Class<?> beanClass, String beanName) throws BeansException; }
public class ProxyFactory { private AdvisedSupport advisedSupport; public ProxyFactory(AdvisedSupport advisedSupport) { this.advisedSupport = advisedSupport; } public Object getProxy() { return createAopProxy().getProxy(); } private AopProxy createAopProxy() { if (advisedSupport.isProxyTargetClass()) { return new Cglib2AopProxy(advisedSupport); } return new JdkDynamicAopProxy(advisedSupport); } }
public class DefaultAdvisorAutoProxyCreator implements InstantiationAwareBeanPostProcessor, BeanFactoryAware { private DefaultListableBeanFactory beanFactory; @Override public void setBeanFactory(BeanFactory beanFactory) throws BeansException { this.beanFactory = (DefaultListableBeanFactory) beanFactory; } @Override public Object postProcessBeforeInstantiation(Class<?> beanClass, String beanName) throws BeansException { if (isInfrastructureClass(beanClass)) return null; Collection<AspectJExpressionPointcutAdvisor> advisors = beanFactory.getBeansOfType(AspectJExpressionPointcutAdvisor.class).values(); for (AspectJExpressionPointcutAdvisor advisor : advisors) { ClassFilter classFilter = advisor.getPointcut().getClassFilter(); if (!classFilter.matches(beanClass)) continue; AdvisedSupport advisedSupport = new AdvisedSupport(); TargetSource targetSource = null; try { targetSource = new TargetSource(beanClass.getDeclaredConstructor().newInstance()); } catch (Exception e) { e.printStackTrace(); } advisedSupport.setTargetSource(targetSource); advisedSupport.setMethodInterceptor((MethodInterceptor) advisor.getAdvice()); advisedSupport.setMethodMatcher(advisor.getPointcut().getMethodMatcher()); advisedSupport.setProxyTargetClass(false); return new ProxyFactory(advisedSupport).getProxy(); } return null; } private boolean isInfrastructureClass(Class<?> beanClass) { return Advice.class.isAssignableFrom(beanClass) || Pointcut.class.isAssignableFrom(beanClass) || Advisor.class.isAssignableFrom(beanClass); } @Override public Object postProcessBeforeInitialization(Object bean, String beanName) throws BeansException { return bean; } @Override public Object postProcessAfterInitialization(Object bean, String beanName) throws BeansException { return bean; } }
public class JdkDynamicAopProxy implements AopProxy, InvocationHandler { private final AdvisedSupport advised; public JdkDynamicAopProxy(AdvisedSupport advised) { this.advised = advised; } @Override public Object getProxy() { return Proxy.newProxyInstance(Thread.currentThread().getContextClassLoader(), advised.getTargetSource().getTargetClass(), this); } @Override public Object invoke(Object proxy, Method method, Object[] args) throws Throwable { if (advised.getMethodMatcher().matches(method, advised.getTargetSource().getTarget().getClass())) { MethodInterceptor methodInterceptor = advised.getMethodInterceptor(); return methodInterceptor.invoke(new ReflectiveMethodInvocation(advised.getTargetSource().getTarget(), method, args)); } return method.invoke(advised.getTargetSource().getTarget(), args); } }
public class Cglib2AopProxy implements AopProxy { private final AdvisedSupport advised; public Cglib2AopProxy(AdvisedSupport advised) { this.advised = advised; } @Override public Object getProxy() { Enhancer enhancer = new Enhancer(); enhancer.setSuperclass(advised.getTargetSource().getTarget().getClass()); enhancer.setInterfaces(advised.getTargetSource().getTargetClass()); enhancer.setCallback(new DynamicAdvisedInterceptor(advised)); return enhancer.create(); } private static class DynamicAdvisedInterceptor implements MethodInterceptor { private final AdvisedSupport advised; public DynamicAdvisedInterceptor(AdvisedSupport advised) { this.advised = advised; } @Override public Object intercept(Object o, Method method, Object[] objects, MethodProxy methodProxy) throws Throwable { CglibMethodInvocation methodInvocation = new CglibMethodInvocation(advised.getTargetSource().getTarget(), method, objects, methodProxy); if (advised.getMethodMatcher().matches(method, advised.getTargetSource().getTarget().getClass())) { return advised.getMethodInterceptor().invoke(methodInvocation); } return methodInvocation.proceed(); } } private static class CglibMethodInvocation extends ReflectiveMethodInvocation { private final MethodProxy methodProxy; public CglibMethodInvocation(Object target, Method method, Object[] arguments, MethodProxy methodProxy) { super(target, method, arguments); this.methodProxy = methodProxy; } @Override public Object proceed() throws Throwable { return this.methodProxy.invoke(this.target, this.arguments); } } }
UT
<?xml version="1.0" encoding="UTF-8"?> <beans> <bean id="userService" class="springframework.bean.UserService"/> <bean class="springframework.aop.framework.autoproxy.DefaultAdvisorAutoProxyCreator"/> <bean id="beforeAdvice" class="springframework.bean.UserServiceBeforeAdvice"/> <bean id="methodInterceptor" class="springframework.aop.framework.adapter.MethodBeforeAdviceInterceptor"> <property name="advice" ref="beforeAdvice"/> </bean> <bean id="pointcutAdvisor" class="springframework.aop.aspectj.AspectJExpressionPointcutAdvisor"> <property name="expression" value="execution(* springframework.bean.IUserService.*(..))"/> <property name="advice" ref="methodInterceptor"/> </bean> </beans>
@Test public void test_aop() { ClassPathXmlApplicationContext applicationContext = new ClassPathXmlApplicationContext("classpath:spring2.xml"); IUserService userService = applicationContext.getBean("userService", IUserService.class); System.out.println("测试结果:" + userService.queryUserInfo()); }
版本V12.0 通过注解配置和包自动扫描的方式完成Bean对象的注册
可以理解为通过xml生成BeanDefinition之外,通过在扫描指定路径中的类,解析类上的特定注释,将特定的类解析为BeanDefinition后,执行后续流程。
PropertyPlaceholderConfigurer类的作用是,作为BeanFactoryPostProcessor,修改benaDefiniton的定义,替换其中的属性值。
public class XmlBeanDefinitionReader extends AbstractBeanDefinitionReader { public XmlBeanDefinitionReader(BeanDefinitionRegistry registry) { super(registry); } public XmlBeanDefinitionReader(BeanDefinitionRegistry registry, ResourceLoader resourceLoader) { super(registry, resourceLoader); } @Override public void loadBeanDefinitions(Resource resource) throws BeansException { try { try (InputStream inputStream = resource.getInputStream()) { doLoadBeanDefinitions(inputStream); } } catch (IOException | ClassNotFoundException | DocumentException e) { throw new BeansException("IOException parsing XML document from " + resource, e); } } @Override public void loadBeanDefinitions(Resource... resources) throws BeansException { for (Resource resource : resources) { loadBeanDefinitions(resource); } } @Override public void loadBeanDefinitions(String location) throws BeansException { ResourceLoader resourceLoader = getResourceLoader(); Resource resource = resourceLoader.getResource(location); loadBeanDefinitions(resource); } @Override public void loadBeanDefinitions(String... locations) throws BeansException { for (String location : locations) { loadBeanDefinitions(location); } } protected void doLoadBeanDefinitions(InputStream inputStream) throws ClassNotFoundException, DocumentException { SAXReader reader = new SAXReader(); Document document = reader.read(inputStream); Element root = document.getRootElement(); // 解析 context:component-scan 标签,扫描包中的类并提取相关信息,用于组装 BeanDefinition Element componentScan = root.element("component-scan"); if (null != componentScan) { String scanPath = componentScan.attributeValue("base-package"); if (StrUtil.isEmpty(scanPath)) { throw new BeansException("The value of base-package attribute can not be empty or null"); } scanPackage(scanPath); } List<Element> beanList = root.elements("bean"); for (Element bean : beanList) { String id = bean.attributeValue("id"); String name = bean.attributeValue("name"); String className = bean.attributeValue("class"); String initMethod = bean.attributeValue("init-method"); String destroyMethodName = bean.attributeValue("destroy-method"); String beanScope = bean.attributeValue("scope"); // 获取 Class,方便获取类中的名称 Class<?> clazz = Class.forName(className); // 优先级 id > name String beanName = StrUtil.isNotEmpty(id) ? id : name; if (StrUtil.isEmpty(beanName)) { beanName = StrUtil.lowerFirst(clazz.getSimpleName()); } // 定义Bean BeanDefinition beanDefinition = new BeanDefinition(clazz); beanDefinition.setInitMethodName(initMethod); beanDefinition.setDestroyMethodName(destroyMethodName); if (StrUtil.isNotEmpty(beanScope)) { beanDefinition.setScope(beanScope); } List<Element> propertyList = bean.elements("property"); // 读取属性并填充 for (Element property : propertyList) { // 解析标签:property String attrName = property.attributeValue("name"); String attrValue = property.attributeValue("value"); String attrRef = property.attributeValue("ref"); // 获取属性值:引入对象、值对象 Object value = StrUtil.isNotEmpty(attrRef) ? new BeanReference(attrRef) : attrValue; // 创建属性信息 PropertyValue propertyValue = new PropertyValue(attrName, value); beanDefinition.getPropertyValues().addPropertyValue(propertyValue); } if (getRegistry().containsBeanDefinition(beanName)) { throw new BeansException("Duplicate beanName[" + beanName + "] is not allowed"); } // 注册 BeanDefinition getRegistry().registerBeanDefinition(beanName, beanDefinition); } } private void scanPackage(String scanPath) { String[] basePackages = StrUtil.splitToArray(scanPath, ','); ClassPathBeanDefinitionScanner scanner = new ClassPathBeanDefinitionScanner(getRegistry()); scanner.doScan(basePackages); } }
public class ClassPathBeanDefinitionScanner extends ClassPathScanningCandidateComponentProvider { private BeanDefinitionRegistry registry; public ClassPathBeanDefinitionScanner(BeanDefinitionRegistry registry) { this.registry = registry; } public void doScan(String... basePackages) { for (String basePackage : basePackages) { Set<BeanDefinition> candidates = findCandidateComponents(basePackage); for (BeanDefinition beanDefinition : candidates) { // 解析 Bean 的作用域 singleton、prototype String beanScope = resolveBeanScope(beanDefinition); if (StrUtil.isNotEmpty(beanScope)) { beanDefinition.setScope(beanScope); } registry.registerBeanDefinition(determineBeanName(beanDefinition), beanDefinition); } } } private String resolveBeanScope(BeanDefinition beanDefinition) { Class<?> beanClass = beanDefinition.getBeanClass(); Scope scope = beanClass.getAnnotation(Scope.class); if (null != scope) return scope.value(); return StrUtil.EMPTY; } private String determineBeanName(BeanDefinition beanDefinition) { Class<?> beanClass = beanDefinition.getBeanClass(); Component component = beanClass.getAnnotation(Component.class); String value = component.value(); if (StrUtil.isEmpty(value)) { value = StrUtil.lowerFirst(beanClass.getSimpleName()); } return value; } }
public class ClassPathScanningCandidateComponentProvider { public Set<BeanDefinition> findCandidateComponents(String basePackage) { Set<BeanDefinition> candidates = new LinkedHashSet<>(); Set<Class<?>> classes = ClassUtil.scanPackageByAnnotation(basePackage, Component.class); for (Class<?> clazz : classes) { candidates.add(new BeanDefinition(clazz)); } return candidates; } }
public class PropertyPlaceholderConfigurer implements BeanFactoryPostProcessor { /** * Default placeholder prefix: {@value} */ public static final String DEFAULT_PLACEHOLDER_PREFIX = "${"; /** * Default placeholder suffix: {@value} */ public static final String DEFAULT_PLACEHOLDER_SUFFIX = "}"; private String location; @Override public void postProcessBeanFactory(ConfigurableListableBeanFactory beanFactory) throws BeansException { // 加载属性文件 try { DefaultResourceLoader resourceLoader = new DefaultResourceLoader(); Resource resource = resourceLoader.getResource(location); Properties properties = new Properties(); properties.load(resource.getInputStream()); String[] beanDefinitionNames = beanFactory.getBeanDefinitionNames(); for (String beanName : beanDefinitionNames) { BeanDefinition beanDefinition = beanFactory.getBeanDefinition(beanName); PropertyValues propertyValues = beanDefinition.getPropertyValues(); for (PropertyValue propertyValue : propertyValues.getPropertyValues()) { Object value = propertyValue.getValue(); if (!(value instanceof String)) continue; String strVal = (String) value; StringBuilder buffer = new StringBuilder(strVal); int startIdx = strVal.indexOf(DEFAULT_PLACEHOLDER_PREFIX); int stopIdx = strVal.indexOf(DEFAULT_PLACEHOLDER_SUFFIX); if (startIdx != -1 && stopIdx != -1 && startIdx < stopIdx) { String propKey = strVal.substring(startIdx + 2, stopIdx); String propVal = properties.getProperty(propKey); buffer.replace(startIdx, stopIdx + 1, propVal); propertyValues.addPropertyValue(new PropertyValue(propertyValue.getName(), buffer.toString())); } } } } catch (IOException e) { throw new BeansException("Could not load properties", e); } } public void setLocation(String location) { this.location = location; } }
UT
<?xml version="1.0" encoding="UTF-8"?> <beans xmlns="http://www.springframework.org/schema/beans" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:context="http://www.springframework.org/schema/context" xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans.xsd http://www.springframework.org/schema/context"> <bean class="springframework.beans.factory.PropertyPlaceholderConfigurer"> <property name="location" value="classpath:token.properties"/> </bean> <bean id="userService" class="springframework.bean.UserService"> <property name="token" value="${token}"/> </bean> </beans>
<?xml version="1.0" encoding="UTF-8"?> <beans xmlns="http://www.springframework.org/schema/beans" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:context="http://www.springframework.org/schema/context" xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans.xsd http://www.springframework.org/schema/context"> <context:component-scan base-package="springframework.bean"/> </beans>
@Test public void test_scan() { ClassPathXmlApplicationContext applicationContext = new ClassPathXmlApplicationContext("classpath:spring-scan.xml"); IUserService userService = applicationContext.getBean("userService", IUserService.class); System.out.println("测试结果:" + userService.queryUserInfo()); } @Test public void test_property() { ClassPathXmlApplicationContext applicationContext = new ClassPathXmlApplicationContext("classpath:spring-property.xml"); IUserService userService = applicationContext.getBean("userService", IUserService.class); System.out.println("测试结果:" + userService); }
@Component("userService") public class UserService implements IUserService { private String token; public String queryUserInfo() { try { Thread.sleep(new Random(1).nextInt(100)); } catch (InterruptedException e) { e.printStackTrace(); } return "a,b,c"; } public String register(String userName) { try { Thread.sleep(new Random(1).nextInt(100)); } catch (InterruptedException e) { e.printStackTrace(); } return "注册用户:" + userName + " success!"; } @Override public String toString() { return "UserService#token = { " + token + " }"; } public String getToken() { return token; } public void setToken(String token) { this.token = token; } }
版本V13.0 通过注解给属性注入配置和Bean对象
实现原理 在AbstractAutowireCapableBeanFactory的createBean方法中 在设置 Bean 属性之前,允许 BeanPostProcessor 修改属性值。
InstantiationAwareBeanPostProcessor中解析@Value,@Autowire, 而@Value的解析参考V10中的PropertyPlaceholderConfigurer
public abstract class AbstractAutowireCapableBeanFactory extends AbstractBeanFactory implements AutowireCapableBeanFactory { private InstantiationStrategy instantiationStrategy = new CglibSubclassingInstantiationStrategy(); @Override protected Object createBean(String beanName, BeanDefinition beanDefinition, Object[] args) throws BeansException { Object bean = null; try { // 判断是否返回代理 Bean 对象 bean = resolveBeforeInstantiation(beanName, beanDefinition); if (null != bean) { return bean; } // 实例化 Bean bean = createBeanInstance(beanDefinition, beanName, args); // 在设置 Bean 属性之前,允许 BeanPostProcessor 修改属性值 applyBeanPostProcessorsBeforeApplyingPropertyValues(beanName, bean, beanDefinition); // 给 Bean 填充属性 applyPropertyValues(beanName, bean, beanDefinition); // 执行 Bean 的初始化方法和 BeanPostProcessor 的前置和后置处理方法 bean = initializeBean(beanName, bean, beanDefinition); } catch (Exception e) { throw new BeansException("Instantiation of bean failed", e); } // 注册实现了 DisposableBean 接口的 Bean 对象 registerDisposableBeanIfNecessary(beanName, bean, beanDefinition); // 判断 SCOPE_SINGLETON、SCOPE_PROTOTYPE if (beanDefinition.isSingleton()) { registerSingleton(beanName, bean); } return bean; } /** * 在设置 Bean 属性之前,允许 BeanPostProcessor 修改属性值 * * @param beanName * @param bean * @param beanDefinition */ protected void applyBeanPostProcessorsBeforeApplyingPropertyValues(String beanName, Object bean, BeanDefinition beanDefinition) { for (BeanPostProcessor beanPostProcessor : getBeanPostProcessors()) { if (beanPostProcessor instanceof InstantiationAwareBeanPostProcessor){ PropertyValues pvs = ((InstantiationAwareBeanPostProcessor) beanPostProcessor).postProcessPropertyValues(beanDefinition.getPropertyValues(), bean, beanName); if (null != pvs) { for (PropertyValue propertyValue : pvs.getPropertyValues()) { beanDefinition.getPropertyValues().addPropertyValue(propertyValue); } } } } } protected Object resolveBeforeInstantiation(String beanName, BeanDefinition beanDefinition) { Object bean = applyBeanPostProcessorsBeforeInstantiation(beanDefinition.getBeanClass(), beanName); if (null != bean) { bean = applyBeanPostProcessorsAfterInitialization(bean, beanName); } return bean; } protected Object applyBeanPostProcessorsBeforeInstantiation(Class<?> beanClass, String beanName) { for (BeanPostProcessor beanPostProcessor : getBeanPostProcessors()) { if (beanPostProcessor instanceof InstantiationAwareBeanPostProcessor) { Object result = ((InstantiationAwareBeanPostProcessor) beanPostProcessor).postProcessBeforeInstantiation(beanClass, beanName); if (null != result) return result; } } return null; } protected void registerDisposableBeanIfNecessary(String beanName, Object bean, BeanDefinition beanDefinition) { // 非 Singleton 类型的 Bean 不执行销毁方法 if (!beanDefinition.isSingleton()) return; if (bean instanceof DisposableBean || StrUtil.isNotEmpty(beanDefinition.getDestroyMethodName())) { registerDisposableBean(beanName, new DisposableBeanAdapter(bean, beanName, beanDefinition)); } } protected Object createBeanInstance(BeanDefinition beanDefinition, String beanName, Object[] args) { Constructor constructorToUse = null; Class<?> beanClass = beanDefinition.getBeanClass(); Constructor<?>[] declaredConstructors = beanClass.getDeclaredConstructors(); for (Constructor ctor : declaredConstructors) { if (null != args && ctor.getParameterTypes().length == args.length) { constructorToUse = ctor; break; } } return getInstantiationStrategy().instantiate(beanDefinition, beanName, constructorToUse, args); } /** * Bean 属性填充 */ protected void applyPropertyValues(String beanName, Object bean, BeanDefinition beanDefinition) { try { PropertyValues propertyValues = beanDefinition.getPropertyValues(); for (PropertyValue propertyValue : propertyValues.getPropertyValues()) { String name = propertyValue.getName(); Object value = propertyValue.getValue(); if (value instanceof BeanReference) { // A 依赖 B,获取 B 的实例化 BeanReference beanReference = (BeanReference) value; value = getBean(beanReference.getBeanName()); } // 属性填充 BeanUtil.setFieldValue(bean, name, value); } } catch (Exception e) { throw new BeansException("Error setting property values:" + beanName); } } public InstantiationStrategy getInstantiationStrategy() { return instantiationStrategy; } public void setInstantiationStrategy(InstantiationStrategy instantiationStrategy) { this.instantiationStrategy = instantiationStrategy; } private Object initializeBean(String beanName, Object bean, BeanDefinition beanDefinition) { // invokeAwareMethods if (bean instanceof Aware) { if (bean instanceof BeanFactoryAware) { ((BeanFactoryAware) bean).setBeanFactory(this); } if (bean instanceof BeanClassLoaderAware) { ((BeanClassLoaderAware) bean).setBeanClassLoader(getBeanClassLoader()); } if (bean instanceof BeanNameAware) { ((BeanNameAware) bean).setBeanName(beanName); } } // 1. 执行 BeanPostProcessor Before 处理 Object wrappedBean = applyBeanPostProcessorsBeforeInitialization(bean, beanName); // 执行 Bean 对象的初始化方法 try { invokeInitMethods(beanName, wrappedBean, beanDefinition); } catch (Exception e) { throw new BeansException("Invocation of init method of bean[" + beanName + "] failed", e); } // 2. 执行 BeanPostProcessor After 处理 wrappedBean = applyBeanPostProcessorsAfterInitialization(wrappedBean, beanName); return wrappedBean; } private void invokeInitMethods(String beanName, Object bean, BeanDefinition beanDefinition) throws Exception { // 1. 实现接口 InitializingBean if (bean instanceof InitializingBean) { ((InitializingBean) bean).afterPropertiesSet(); } // 2. 注解配置 init-method {判断是为了避免二次执行销毁} String initMethodName = beanDefinition.getInitMethodName(); if (StrUtil.isNotEmpty(initMethodName)) { Method initMethod = beanDefinition.getBeanClass().getMethod(initMethodName); if (null == initMethod) { throw new BeansException("Could not find an init method named '" + initMethodName + "' on bean with name '" + beanName + "'"); } initMethod.invoke(bean); } } @Override public Object applyBeanPostProcessorsBeforeInitialization(Object existingBean, String beanName) throws BeansException { Object result = existingBean; for (BeanPostProcessor processor : getBeanPostProcessors()) { Object current = processor.postProcessBeforeInitialization(result, beanName); if (null == current) return result; result = current; } return result; } @Override public Object applyBeanPostProcessorsAfterInitialization(Object existingBean, String beanName) throws BeansException { Object result = existingBean; for (BeanPostProcessor processor : getBeanPostProcessors()) { Object current = processor.postProcessAfterInitialization(result, beanName); if (null == current) return result; result = current; } return result; } }
public interface InstantiationAwareBeanPostProcessor extends BeanPostProcessor { /** * Apply this BeanPostProcessor <i>before the target bean gets instantiated</i>. * The returned bean object may be a proxy to use instead of the target bean, * effectively suppressing default instantiation of the target bean. * <p> * 在 Bean 对象执行初始化方法之前,执行此方法 * * @param beanClass * @param beanName * @return * @throws BeansException */ Object postProcessBeforeInstantiation(Class<?> beanClass, String beanName) throws BeansException; PropertyValues postProcessPropertyValues(PropertyValues pvs, Object bean, String beanName); }
public class AutowiredAnnotationBeanPostProcessor implements InstantiationAwareBeanPostProcessor, BeanFactoryAware { private ConfigurableListableBeanFactory beanFactory; @Override public void setBeanFactory(BeanFactory beanFactory) throws BeansException { this.beanFactory = (ConfigurableListableBeanFactory) beanFactory; } @Override public PropertyValues postProcessPropertyValues(PropertyValues pvs, Object bean, String beanName) throws BeansException { // 1. 处理注解 @Value Class<?> clazz = bean.getClass(); clazz = ClassUtils.isCglibProxyClass(clazz) ? clazz.getSuperclass() : clazz; Field[] declaredFields = clazz.getDeclaredFields(); for (Field field : declaredFields) { Value valueAnnotation = field.getAnnotation(Value.class); if (null != valueAnnotation) { String value = valueAnnotation.value(); value = beanFactory.resolveEmbeddedValue(value); BeanUtil.setFieldValue(bean, field.getName(), value); } } // 2. 处理注解 @Autowired for (Field field : declaredFields) { Autowired autowiredAnnotation = field.getAnnotation(Autowired.class); if (null != autowiredAnnotation) { Class<?> fieldType = field.getType(); String dependentBeanName = null; Qualifier qualifierAnnotation = field.getAnnotation(Qualifier.class); Object dependentBean = null; if (null != qualifierAnnotation) { dependentBeanName = qualifierAnnotation.value(); dependentBean = beanFactory.getBean(dependentBeanName, fieldType); } else { dependentBean = beanFactory.getBean(fieldType); } BeanUtil.setFieldValue(bean, field.getName(), dependentBean); } } return pvs; } @Override public Object postProcessBeforeInstantiation(Class<?> beanClass, String beanName) throws BeansException { return null; } @Override public Object postProcessBeforeInitialization(Object bean, String beanName) throws BeansException { return null; } @Override public Object postProcessAfterInitialization(Object bean, String beanName) throws BeansException { return null; } }
public class PropertyPlaceholderConfigurer implements BeanFactoryPostProcessor { /** * Default placeholder prefix: {@value} */ public static final String DEFAULT_PLACEHOLDER_PREFIX = "${"; /** * Default placeholder suffix: {@value} */ public static final String DEFAULT_PLACEHOLDER_SUFFIX = "}"; private String location; @Override public void postProcessBeanFactory(ConfigurableListableBeanFactory beanFactory) throws BeansException { // 加载属性文件 try { DefaultResourceLoader resourceLoader = new DefaultResourceLoader(); Resource resource = resourceLoader.getResource(location); Properties properties = new Properties(); properties.load(resource.getInputStream()); String[] beanDefinitionNames = beanFactory.getBeanDefinitionNames(); for (String beanName : beanDefinitionNames) { BeanDefinition beanDefinition = beanFactory.getBeanDefinition(beanName); PropertyValues propertyValues = beanDefinition.getPropertyValues(); for (PropertyValue propertyValue : propertyValues.getPropertyValues()) { Object value = propertyValue.getValue(); if (!(value instanceof String)) continue; String strVal = (String) value; StringBuilder buffer = new StringBuilder(strVal); int startIdx = strVal.indexOf(DEFAULT_PLACEHOLDER_PREFIX); int stopIdx = strVal.indexOf(DEFAULT_PLACEHOLDER_SUFFIX); if (startIdx != -1 && stopIdx != -1 && startIdx < stopIdx) { String propKey = strVal.substring(startIdx + 2, stopIdx); String propVal = properties.getProperty(propKey); buffer.replace(startIdx, stopIdx + 1, propVal); propertyValues.addPropertyValue(new PropertyValue(propertyValue.getName(), buffer.toString())); } } // 向容器中添加字符串解析器,供解析@Value注解使用 StringValueResolver valueResolver = new PlaceholderResolvingStringValueResolver(properties); beanFactory.addEmbeddedValueResolver(valueResolver); } } catch (IOException e) { throw new BeansException("Could not load properties", e); } } public void setLocation(String location) { this.location = location; } private String resolvePlaceholder(String value, Properties properties) { String strVal = value; StringBuilder buffer = new StringBuilder(strVal); int startIdx = strVal.indexOf(DEFAULT_PLACEHOLDER_PREFIX); int stopIdx = strVal.indexOf(DEFAULT_PLACEHOLDER_SUFFIX); if (startIdx != -1 && stopIdx != -1 && startIdx < stopIdx) { String propKey = strVal.substring(startIdx + 2, stopIdx); String propVal = properties.getProperty(propKey); buffer.replace(startIdx, stopIdx + 1, propVal); } return buffer.toString(); } private class PlaceholderResolvingStringValueResolver implements StringValueResolver { private final Properties properties; public PlaceholderResolvingStringValueResolver(Properties properties) { this.properties = properties; } @Override public String resolveStringValue(String strVal) { return PropertyPlaceholderConfigurer.this.resolvePlaceholder(strVal, properties); } } }
public interface ConfigurableBeanFactory extends HierarchicalBeanFactory, SingletonBeanRegistry { String SCOPE_SINGLETON = "singleton"; String SCOPE_PROTOTYPE = "prototype"; void addBeanPostProcessor(BeanPostProcessor beanPostProcessor); /** * 销毁单例对象 */ void destroySingletons(); /** * Resolve the given embedded value, e.g. an annotation attribute. * @param value the value to resolve * @return the resolved value (may be the original value as-is) * @since 3.0 */ String resolveEmbeddedValue(String value); void addEmbeddedValueResolver(StringValueResolver valueResolver); }
UT
@Component("userService") public class UserService implements IUserService { @Value("${token}") private String token; @Autowired private UserDao userDao; public String queryUserInfo() { try { Thread.sleep(new Random(1).nextInt(100)); } catch (InterruptedException e) { e.printStackTrace(); } return userDao.queryUserName("10001") + "," + token; } public String register(String userName) { try { Thread.sleep(new Random(1).nextInt(100)); } catch (InterruptedException e) { e.printStackTrace(); } return "注册用户:" + userName + " success!"; } @Override public String toString() { return "UserService#token = { " + token + " }"; } public String getToken() { return token; } public void setToken(String token) { this.token = token; } public UserDao getUserDao() { return userDao; } public void setUserDao(UserDao userDao) { this.userDao = userDao; } }
<?xml version="1.0" encoding="UTF-8"?> <beans xmlns="http://www.springframework.org/schema/beans" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:context="http://www.springframework.org/schema/context" xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans.xsd http://www.springframework.org/schema/context"> <bean class="springframework.beans.factory.PropertyPlaceholderConfigurer"> <property name="location" value="classpath:token.properties"/> </bean> <context:component-scan base-package="springframework.bean"/> </beans>
版本V14.0 给代理对象的属性设置值
在V13版本中,是在 InstantiationAwareBeanPostProcessor.postProcessBeforeInstantiation中实现的,在对象实例化之前进行代理对象的生成,但是这样会造成提前返回,而错过属性值的赋值。 所以现在将代理逻辑由 InstantiationAwareBeanPostProcessor.postProcessBeforeInstantiation迁移到DefaultAdvisorAutoProxyCreator.postProcessAfterInitialization。
其中可能会遇到因为代理而遇到的各种问题。这里将实例化策略更换为SimpleInstantiationStrategy,并且将代理实现逻辑更为JdkDynamicAopProxy。
参考:
https://github.com/DerekYRC/mini-spring/blob/main/changelog.md#bug-fix%E6%B2%A1%E6%9C%89%E4%B8%BA%E4%BB%A3%E7%90%86bean%E8%AE%BE%E7%BD%AE%E5%B1%9E%E6%80%A7discovered-and-fixed-by-kerwin89
ps:自己定位问题才是理解这套框架最佳的学习方式。
版本V15.0 通过三级缓存解决循环依赖
1简单版本的循环依赖问题 ,不存在代理对象的循环依赖
public class A { public B getB() { return b; } public void setB(B b) { this.b = b; } private B b; } public class B { public A getA() { return a; } public void setA(A a) { this.a = a; } private A a; }
<?xml version="1.0" encoding="UTF-8"?> <beans xmlns="http://www.springframework.org/schema/beans" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans.xsd"> <bean id="A" class="springframework.bean.A"> <property name="b" ref="B"/> </bean> <bean id="B" class="springframework.bean.B"> <property name="a" ref="A"/> </bean> </beans>
由于在getBean(A) 中需要 getBean(B),getBean(B)中又需要 getBean(A),死循环会造成栈溢出。
仔细分析原因是由于我们在AbstractBeanFactory getSingleton(beanName) 与在AbstractAutowireCapableBeanFactory registerSingleton(beanName, exposedObject)的时机问题。
当前我们是在bean实例化并初始化后才会将单例注册进singletonObjects,如果在bean实例化后,就提前注入到singletonObjects。这样就能避免简单的循环依赖,为了将初始化并给属性值赋值后的bean与仅完成实例化的bean区分来,我们将后者放入earlySingletonObjects。 getSingleton时先尝试获取singletonObjects中的bean,如果没有的话在尝试从earlySingletonObjects获取bean。
public abstract class AbstractAutowireCapableBeanFactory extends AbstractBeanFactory implements AutowireCapableBeanFactory { private InstantiationStrategy instantiationStrategy = new SimpleInstantiationStrategy(); @Override protected Object createBean(String beanName, BeanDefinition beanDefinition, Object[] args) throws BeansException { // 判断是否返回代理 Bean 对象 Object bean = resolveBeforeInstantiation(beanName, beanDefinition); if (null != bean) { return bean; } return doCreateBean(beanName, beanDefinition, args); } protected Object doCreateBean(String beanName, BeanDefinition beanDefinition, Object[] args) throws BeansException { Object bean = null; try { // 实例化 Bean bean = createBeanInstance(beanDefinition, beanName, args); if (beanDefinition.isSingleton()) { // 二级缓存 registerEarlySingleton(beanName, bean); } // 实例化后判断 boolean continueWithPropertyPopulation = applyBeanPostProcessorsAfterInstantiation(beanName, bean); if (!continueWithPropertyPopulation) { return bean; } // 在设置 Bean 属性之前,允许 BeanPostProcessor 修改属性值 applyBeanPostProcessorsBeforeApplyingPropertyValues(beanName, bean, beanDefinition); // 给 Bean 填充属性 applyPropertyValues(beanName, bean, beanDefinition); // 执行 Bean 的初始化方法和 BeanPostProcessor 的前置和后置处理方法 bean = initializeBean(beanName, bean, beanDefinition); } catch (Exception e) { throw new BeansException("Instantiation of bean failed", e); } // 注册实现了 DisposableBean 接口的 Bean 对象 registerDisposableBeanIfNecessary(beanName, bean, beanDefinition); // 判断 SCOPE_SINGLETON、SCOPE_PROTOTYPE Object exposedObject = bean; if (beanDefinition.isSingleton()) { // registerSingleton(beanName, bean); // 获取代理对象 // exposedObject = getSingleton(beanName); registerSingleton(beanName, exposedObject); } return bean; }}
public class DefaultSingletonBeanRegistry implements SingletonBeanRegistry { /** * Internal marker for a null singleton object: * used as marker value for concurrent Maps (which don't support null values). */ protected static final Object NULL_OBJECT = new Object(); private final Map<String, DisposableBean> disposableBeans = new HashMap<>(); // 一级缓存,普通对象 /** * Cache of singleton objects: bean name --> bean instance */ private Map<String, Object> singletonObjects = new ConcurrentHashMap<>(); // 二级缓存,提前暴漏对象,没有完全实例化的对象 /** * Cache of early singleton objects: bean name --> bean instance */ protected final Map<String, Object> earlySingletonObjects = new HashMap<String, Object>(); // 三级缓存,存放代理对象 /** * Cache of singleton factories: bean name --> ObjectFactory */ private final Map<String, ObjectFactory<?>> singletonFactories = new HashMap<String, ObjectFactory<?>>(); @Override public Object getSingleton(String beanName) { Object singletonObject = singletonObjects.get(beanName); if (singletonObject != null) { return singletonObject; } return earlySingletonObjects.get(beanName); } public void registerEarlySingleton(String beanName, Object singletonObject) { earlySingletonObjects.put(beanName, singletonObject); } @Override public void registerSingleton(String beanName, Object singletonObject) { singletonObjects.put(beanName, singletonObject); } public void registerDisposableBean(String beanName, DisposableBean bean) { disposableBeans.put(beanName, bean); } public void destroySingletons() { Set<String> keySet = this.disposableBeans.keySet(); Object[] disposableBeanNames = keySet.toArray(); for (int i = disposableBeanNames.length - 1; i >= 0; i--) { Object beanName = disposableBeanNames[i]; DisposableBean disposableBean = disposableBeans.remove(beanName); try { disposableBean.destroy(); } catch (Exception e) { throw new BeansException("Destroy method on bean with name '" + beanName + "' threw an exception", e); } } } }
这样简单循环依赖解决了。
2.【解决有代理对象时的循环依赖问题,需要提前暴露代理对象的引用,而不是暴露实例化后的bean的引用(这是上节的遗留问题的原因,应该提前暴露A的代理对象的引用)。
spring中用singletonFactories(一般称第三级缓存)解决有代理对象时的循环依赖问题。在实例化后提前暴露代理对象的引用(见AbstractAutowireCapableBeanFactory#doCreateBean方法第6行)。
getBean()时依次检查一级缓存singletonObjects、二级缓存earlySingletonObjects和三级缓存singletonFactories中是否包含该bean。如果三级缓存中包含该bean,则挪至二级缓存中,然后直接返回该bean。见AbstractBeanFactory#getBean方法第1行。
最后将代理bean放进一级缓存singletonObjects,见AbstractAutowireCapableBeanFactory第104行】
public abstract class AbstractAutowireCapableBeanFactory extends AbstractBeanFactory implements AutowireCapableBeanFactory { private InstantiationStrategy instantiationStrategy = new SimpleInstantiationStrategy(); @Override protected Object createBean(String beanName, BeanDefinition beanDefinition) throws BeansException { //如果bean需要代理,则直接返回代理对象 Object bean = resolveBeforeInstantiation(beanName, beanDefinition); if (bean != null) { return bean; } return doCreateBean(beanName, beanDefinition); } /** * 执行InstantiationAwareBeanPostProcessor的方法,如果bean需要代理,直接返回代理对象 * * @param beanName * @param beanDefinition * @return */ protected Object resolveBeforeInstantiation(String beanName, BeanDefinition beanDefinition) { Object bean = applyBeanPostProcessorsBeforeInstantiation(beanDefinition.getBeanClass(), beanName); if (bean != null) { bean = applyBeanPostProcessorsAfterInitialization(bean, beanName); } return bean; } protected Object applyBeanPostProcessorsBeforeInstantiation(Class beanClass, String beanName) { for (BeanPostProcessor beanPostProcessor : getBeanPostProcessors()) { if (beanPostProcessor instanceof InstantiationAwareBeanPostProcessor) { Object result = ((InstantiationAwareBeanPostProcessor) beanPostProcessor).postProcessBeforeInstantiation(beanClass, beanName); if (result != null) { return result; } } } return null; } protected Object doCreateBean(String beanName, BeanDefinition beanDefinition) { Object bean; try { bean = createBeanInstance(beanDefinition); //为解决循环依赖问题,将实例化后的bean放进缓存中提前暴露 if (beanDefinition.isSingleton()) { Object finalBean = bean; addSingletonFactory(beanName, new ObjectFactory<Object>() { @Override public Object getObject() throws BeansException { return getEarlyBeanReference(beanName, beanDefinition, finalBean); } }); } //实例化bean之后执行 boolean continueWithPropertyPopulation = applyBeanPostProcessorsAfterInstantiation(beanName, bean); if (!continueWithPropertyPopulation) { return bean; } //在设置bean属性之前,允许BeanPostProcessor修改属性值 applyBeanPostProcessorsBeforeApplyingPropertyValues(beanName, bean, beanDefinition); //为bean填充属性 applyPropertyValues(beanName, bean, beanDefinition); //执行bean的初始化方法和BeanPostProcessor的前置和后置处理方法 bean = initializeBean(beanName, bean, beanDefinition); } catch (Exception e) { throw new BeansException("Instantiation of bean failed", e); } //注册有销毁方法的bean registerDisposableBeanIfNecessary(beanName, bean, beanDefinition); Object exposedObject = bean; if (beanDefinition.isSingleton()) { //如果有代理对象,此处获取代理对象 exposedObject = getSingleton(beanName); addSingleton(beanName, exposedObject); } return exposedObject; } protected Object getEarlyBeanReference(String beanName, BeanDefinition beanDefinition, Object bean) { Object exposedObject = bean; for (BeanPostProcessor bp : getBeanPostProcessors()) { if (bp instanceof InstantiationAwareBeanPostProcessor) { exposedObject = ((InstantiationAwareBeanPostProcessor) bp).getEarlyBeanReference(exposedObject, beanName); if (exposedObject == null) { return exposedObject; } } } return exposedObject; }
public class DefaultAdvisorAutoProxyCreator implements InstantiationAwareBeanPostProcessor, BeanFactoryAware { private DefaultListableBeanFactory beanFactory; private Set<Object> earlyProxyReferences = new HashSet<>(); @Override public Object postProcessAfterInitialization(Object bean, String beanName) throws BeansException { if (!earlyProxyReferences.contains(beanName)) { return wrapIfNecessary(bean, beanName); } return bean; } @Override public Object getEarlyBeanReference(Object bean, String beanName) throws BeansException { earlyProxyReferences.add(beanName); return wrapIfNecessary(bean, beanName); } protected Object wrapIfNecessary(Object bean, String beanName) { //避免死循环 if (isInfrastructureClass(bean.getClass())) { return bean; } Collection<AspectJExpressionPointcutAdvisor> advisors = beanFactory.getBeansOfType(AspectJExpressionPointcutAdvisor.class).values(); try { for (AspectJExpressionPointcutAdvisor advisor : advisors) { ClassFilter classFilter = advisor.getPointcut().getClassFilter(); if (classFilter.matches(bean.getClass())) { AdvisedSupport advisedSupport = new AdvisedSupport(); TargetSource targetSource = new TargetSource(bean); advisedSupport.setTargetSource(targetSource); advisedSupport.setMethodInterceptor((MethodInterceptor) advisor.getAdvice()); advisedSupport.setMethodMatcher(advisor.getPointcut().getMethodMatcher()); //返回代理对象 return new ProxyFactory(advisedSupport).getProxy(); } } } catch (Exception ex) { throw new BeansException("Error create proxy bean for: " + beanName, ex); } return bean; } private boolean isInfrastructureClass(Class<?> beanClass) { return Advice.class.isAssignableFrom(beanClass) || Pointcut.class.isAssignableFrom(beanClass) || Advisor.class.isAssignableFrom(beanClass); } @Override public void setBeanFactory(BeanFactory beanFactory) throws BeansException { this.beanFactory = (DefaultListableBeanFactory) beanFactory; } @Override public Object postProcessBeforeInstantiation(Class<?> beanClass, String beanName) throws BeansException { return null; } @Override public boolean postProcessAfterInstantiation(Object bean, String beanName) throws BeansException { return true; } @Override public Object postProcessBeforeInitialization(Object bean, String beanName) throws BeansException { return bean; } @Override public PropertyValues postProcessPropertyValues(PropertyValues pvs, Object bean, String beanName) throws BeansException { return pvs; } }
public class DefaultSingletonBeanRegistry implements SingletonBeanRegistry { //一级缓存 private Map<String, Object> singletonObjects = new HashMap<>(); //二级缓存 private Map<String, Object> earlySingletonObjects = new HashMap<>(); //三级缓存 private Map<String, ObjectFactory<?>> singletonFactories = new HashMap<String, ObjectFactory<?>>(); private final Map<String, DisposableBean> disposableBeans = new HashMap<>(); @Override public Object getSingleton(String beanName) { Object singletonObject = singletonObjects.get(beanName); if (singletonObject == null) { singletonObject = earlySingletonObjects.get(beanName); if (singletonObject == null) { ObjectFactory<?> singletonFactory = singletonFactories.get(beanName); if (singletonFactory != null) { singletonObject = singletonFactory.getObject(); //从三级缓存放进二级缓存 earlySingletonObjects.put(beanName, singletonObject); singletonFactories.remove(beanName); } } } return singletonObject; } @Override public void addSingleton(String beanName, Object singletonObject) { singletonObjects.put(beanName, singletonObject); earlySingletonObjects.remove(beanName); singletonFactories.remove(beanName); } protected void addSingletonFactory(String beanName, ObjectFactory<?> singletonFactory) { singletonFactories.put(beanName, singletonFactory); } public void registerDisposableBean(String beanName, DisposableBean bean) { disposableBeans.put(beanName, bean); } public void destroySingletons() { Set<String> beanNames = disposableBeans.keySet(); for (String beanName : beanNames) { DisposableBean disposableBean = disposableBeans.remove(beanName); try { disposableBean.destroy(); } catch (Exception e) { throw new BeansException("Destroy method on bean with name '" + beanName + "' threw an exception", e); } } } }
<?xml version="1.0" encoding="UTF-8"?> <beans xmlns="http://www.springframework.org/schema/beans" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:context="http://www.springframework.org/schema/context" xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans.xsd http://www.springframework.org/schema/context http://www.springframework.org/schema/context/spring-context-4.0.xsd"> <bean id="b" class="org.springframework.test.bean.B"> <property name="a" ref="a"/> </bean> <!-- a被代理 --> <bean id="a" class="org.springframework.test.bean.A"> <property name="b" ref="b"/> </bean> <bean class="org.springframework.aop.framework.autoproxy.DefaultAdvisorAutoProxyCreator"/> <bean id="pointcutAdvisor" class="org.springframework.aop.aspectj.AspectJExpressionPointcutAdvisor"> <property name="expression" value="execution(* org.springframework.test.bean.A.func(..))"/> <property name="advice" ref="methodInterceptor"/> </bean> <bean id="methodInterceptor" class="org.springframework.aop.framework.adapter.MethodBeforeAdviceInterceptor"> <property name="advice" ref="beforeAdvice"/> </bean> <bean id="beforeAdvice" class="org.springframework.test.common.ABeforeAdvice"/> </beans>
此时 A对象会被代理,所以B对象中的A引用也应该是代理对象。
完结,撒花🎉🎉🎉🎉