如何给代理对象中的属性填充相应的值?
设计:把创建代理对象的逻辑迁移到对象执行初始化之后。
DefaultAdvisorAutoProxyCreator
实现的 InstantiationAwareBeanPostProcessor
接口。Before
中的操作,则需要放到 After
中处理createBean
的生命周期中,有一个阶段是在 Bean 对象属性填充完成以后,执行 Bean 的初始化方法和 BeanPostProcessor
的前置和后置处理。
Aware
对象、处理 init-method
方法等。BeanPostProcessor After
就可以用于创建处理对象操作。DefaultAdvisorAutoProxyCreator
用于创建代理对象的操作中,需要把创建操作从 postProcessBeforeInstantiation
方法中迁移到 postProcessAfterInitialization
,这样才能满足 Bean 属性填充后的创建操作。spring-step-15
|-src
|-main
| |-java
| |-com.lino.springframework
| |-aop
| | |-aspectj
| | | |-AspectJExpressionPointcut.java
| | | |-AspectJExpressionPointcutAdvisor.java
| | |-framework
| | | |-adapter
| | | | |-MethodBeforeAdviceInterceptor.java
| | | |-autoproxy
| | | | |-DefaultAdvisorAutoProxyCreator.java
| | | |-AopProxy.java
| | | |-Cglib2AopProxy.java
| | | |-JdkDynamicAopProxy.java
| | | |-ProxyFactory.java
| | | |-ReflectiveMethodInvocation.java
| | |-AdvisedSupport.java
| | |-Advisor.java
| | |-BeforeAdvice.java
| | |-ClassFilter.java
| | |-MethodBeforeAdvice.java
| | |-MethodMatcher.java
| | |-Pointcut.java
| | |-PointcutAdvisor.java
| | |-TargetSource.java
| |-beans
| | |-factory
| | | |-annotation
| | | | |-Autowired.java
| | | | |-AutowiredAnnotationBeanPostProcessor.java
| | | | |-Qualifier.java
| | | | |-Value.java
| | | |-config
| | | | |-AutowireCapableBeanFactory.java
| | | | |-BeanDefinition.java
| | | | |-BeanFactoryPostProcessor.java
| | | | |-BeanPostProcessor.java
| | | | |-BeanReference.java
| | | | |-ConfigurableBeanFactory.java
| | | | |-InstantiationAwareBeanPostProcessor.java
| | | | |-SingletonBeanRegistry.java
| | | |-support
| | | | |-AbstractAutowireCapableBeanFactory.java
| | | | |-AbstractBeabDefinitionReader.java
| | | | |-AbstractBeabFactory.java
| | | | |-BeabDefinitionReader.java
| | | | |-BeanDefinitionRegistry.java
| | | | |-CglibSubclassingInstantiationStrategy.java
| | | | |-DefaultListableBeanFactory.java
| | | | |-DefaultSingletonBeanRegistry.java
| | | | |-DisposableBeanAdapter.java
| | | | |-FactoryBeanRegistrySupport.java
| | | | |-InstantiationStrategy.java
| | | | |-SimpleInstantiationStrategy.java
| | | |-xml
| | | | |-XmlBeanDefinitionReader.java
| | | |-Aware.java
| | | |-BeanClassLoaderAware.java
| | | |-BeanFactory.java
| | | |-BeanFactoryAware.java
| | | |-BeanNameAware.java
| | | |-ConfigurableListableBeanFactory.java
| | | |-DisposableBean.java
| | | |-FactoryBean.java
| | | |-HierarcgicalBeanFactory.java
| | | |-InitializingBean.java
| | | |-ListableBeanFactory.java
| | | |-PropertyPlaceholderConfigurer.java
| | |-BeansException.java
| | |-PropertyValue.java
| | |-PropertyValues.java
| |-context
| | |-annotation
| | | |-ClassPathBeanDefinitionScanner.java
| | | |-ClassPathScanningCandidateComponentProvider.java
| | | |-Scope.java
| | |-event
| | | |-AbstractApplicationEventMulticaster.java
| | | |-ApplicationContextEvent.java
| | | |-ApplicationEventMulticaster.java
| | | |-ContextclosedEvent.java
| | | |-ContextRefreshedEvent.java
| | | |-SimpleApplicationEventMulticaster.java
| | |-support
| | | |-AbstractApplicationContext.java
| | | |-AbstractRefreshableApplicationContext.java
| | | |-AbstractXmlApplicationContext.java
| | | |-ApplicationContextAwareProcessor.java
| | | |-ClassPathXmlApplicationContext.java
| | |-ApplicationContext.java
| | |-ApplicationContextAware.java
| | |-ApplicationEvent.java
| | |-ApplicationEventPublisher.java
| | |-ApplicationListener.java
| | |-ConfigurableApplicationContext.java
| |-core.io
| | |-ClassPathResource.java
| | |-DefaultResourceLoader.java
| | |-FileSystemResource.java
| | |-Resource.java
| | |-ResourceLoader.java
| | |-UrlResource.java
| |-stereotype
| | |-Component.java
| |-util
| | |-ClassUtils.java
| | |-StringValueResolver.java
|-test
|-java
|-com.lino.springframework.test
|-bean
| |-IUserService.java
| |-UserService.java
| |-UserServiceBeforeAdvice.java
|-ApiTest.java
|-resources
|-spring.xml
|-token.properties
初始化 initializeBean
)中处理代理类的创建。DefaultAdvisorAutoProxyCreator
类创建代理对象的操作放置在 postProcessAfterInitialization
方法中。AbstractAutowireCapableBeanFactory
完成初始化方法的调用操作。AbstractAutowireCapableBeanFactory
类里使用的是 CglibSubclassingInstantiationStrategy
创建对象,所有有需要判断对象获取接口的方法中,也都需要判断是否为 CGLIB 创建,否则是不能正确获取到接口的。
ClassUtils.isCglibProxyClass(clazz) ? clazz.getSuperclass() : clazz
TargetSource.java
package com.lino.springframework.aop;
import com.lino.springframework.util.ClassUtils;
/**
* @description: 被代理的目标对象
*/
public class TargetSource {
private final Object target;
public TargetSource(Object target) {
this.target = target;
}
/**
* 获取目标对象列表
*
* @return 目标对象列表
*/
public Class<?>[] getTargetClass() {
Class<?> clazz = this.target.getClass();
clazz = ClassUtils.isCglibProxyClass(clazz) ? clazz.getSuperclass() : clazz;
return clazz.getInterfaces();
}
/**
* 获取目标对象
*
* @return 目标对象
*/
public Object getTarget() {
return this.target;
}
}
TargetSource#getTargetClass
是用于获取 target
对象的接口信息的,那么这个 target
可以是 JDK 代理创建,也可能是 CGLIB 创建。ClassUtils.isCglibProxyClass(clazz)
。InstantiationAwareBeanPostProcessor.java
package com.lino.springframework.beans.factory.config;
import com.lino.springframework.beans.BeansException;
import com.lino.springframework.beans.PropertyValues;
/**
* @description: 实例化感知对象处理
*/
public interface InstantiationAwareBeanPostProcessor extends BeanPostProcessor {
/**
* 在 Bean 对象执行初始化方法之前,执行此方法
*
* @param beanClass 对象类
* @param beanName 对象名
* @return 新对象
* @throws BeansException 异常
*/
Object postProcessBeforeInstantiation(Class<?> beanClass, String beanName) throws BeansException;
/**
* 在 Bean 对象执行初始化方法之后,执行此方法
*
* @param bean 对象
* @param beanName 对象名称
* @return 是否执行
* @throws BeansException 异常
*/
boolean postProcessAfterInstantiation(Object bean, String beanName) throws BeansException;
/**
* 在 Bean 对象实例化完成后,设置属性操作之前执行此方法
*
* @param pvs 属性值集合
* @param bean 对象
* @param beanName 对象名称
* @return 属性值集合
* @throws BeansException 异常
*/
PropertyValues postProcessPropertyValues(PropertyValues pvs, Object bean, String beanName) throws BeansException;
}
AutowiredAnnotationBeanPostProcessor.java
package com.lino.springframework.beans.factory.annotation;
import cn.hutool.core.bean.BeanUtil;
import com.lino.springframework.beans.BeansException;
import com.lino.springframework.beans.PropertyValues;
import com.lino.springframework.beans.factory.BeanFactory;
import com.lino.springframework.beans.factory.BeanFactoryAware;
import com.lino.springframework.beans.factory.config.ConfigurableBeanFactory;
import com.lino.springframework.beans.factory.config.InstantiationAwareBeanPostProcessor;
import com.lino.springframework.util.ClassUtils;
import java.lang.reflect.Field;
/**
* @description: 扫描自定义注解类
*/
public class AutowiredAnnotationBeanPostProcessor implements InstantiationAwareBeanPostProcessor, BeanFactoryAware {
...
@Override
public Object postProcessBeforeInitialization(Object bean, String beanName) throws BeansException {
return null;
}
@Override
public Object postProcessAfterInitialization(Object bean, String beanName) throws BeansException {
return null;
}
@Override
public Object postProcessBeforeInstantiation(Class<?> beanClass, String beanName) throws BeansException {
return null;
}
@Override
public boolean postProcessAfterInstantiation(Object bean, String beanName) throws BeansException {
return true;
}
}
DefaultAdvisorAutoProxyCreator.java
package com.lino.springframework.aop.framework.autoproxy;
import com.lino.springframework.aop.*;
import com.lino.springframework.aop.aspectj.AspectJExpressionPointcutAdvisor;
import com.lino.springframework.aop.framework.ProxyFactory;
import com.lino.springframework.beans.BeansException;
import com.lino.springframework.beans.PropertyValues;
import com.lino.springframework.beans.factory.BeanFactory;
import com.lino.springframework.beans.factory.BeanFactoryAware;
import com.lino.springframework.beans.factory.config.InstantiationAwareBeanPostProcessor;
import com.lino.springframework.beans.factory.support.DefaultListableBeanFactory;
import org.aopalliance.aop.Advice;
import org.aopalliance.intercept.MethodInterceptor;
import java.util.Collection;
/**
* @description: 默认自动代理创建者
*/
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 {
return null;
}
@Override
public boolean postProcessAfterInstantiation(Object bean, String beanName) throws BeansException {
return true;
}
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 {
if (isInfrastructureClass(bean.getClass())) {
return bean;
}
Collection<AspectJExpressionPointcutAdvisor> advisors = beanFactory.getBeansOfType(AspectJExpressionPointcutAdvisor.class).values();
for (AspectJExpressionPointcutAdvisor advisor : advisors) {
ClassFilter classFilter = advisor.getPointcut().getClassFilter();
// 过滤匹配类
if (!classFilter.matches(bean.getClass())) {
continue;
}
AdvisedSupport advisedSupport = new AdvisedSupport();
TargetSource targetSource = new TargetSource(bean);
advisedSupport.setTargetSource(targetSource);
advisedSupport.setMethodInterceptor((MethodInterceptor) advisor.getAdvice());
advisedSupport.setMethodMatcher(advisor.getPointcut().getMethodMatcher());
advisedSupport.setProxyTargetClass(false);
// 返回代理对象
return new ProxyFactory(advisedSupport).getProxy();
}
return bean;
}
@Override
public PropertyValues postProcessPropertyValues(PropertyValues pvs, Object bean, String beanName) throws BeansException {
return pvs;
}
}
DefaultAdvisorAutoProxyCreator
类的操作主要就是把创建 AOP 代理的操作从 postProcessBeforeInstantiation
移动到 postProcessAfterInitialization
中。new ProxyFactory(advisedSupport).getProxy()
。
TargetSource#getTargetClass
的获取。AbstractAutowireCapableBeanFactory.java
package com.lino.springframework.beans.factory.support;
import cn.hutool.core.bean.BeanUtil;
import cn.hutool.core.util.StrUtil;
import com.lino.springframework.beans.BeansException;
import com.lino.springframework.beans.PropertyValue;
import com.lino.springframework.beans.PropertyValues;
import com.lino.springframework.beans.factory.*;
import com.lino.springframework.beans.factory.config.*;
import java.lang.reflect.Constructor;
import java.lang.reflect.Method;
/**
* @description: 实现默认bean创建的抽象bean工厂超类
* @author: lingjian
* @createDate: 2022/11/22 14:39
*/
public abstract class AbstractAutowireCapableBeanFactory extends AbstractBeanFactory implements AutowireCapableBeanFactory {
private InstantiationStrategy instantiationStrategy = new CglibSubclassingInstantiationStrategy();
@Override
protected Object createBean(String beanName, BeanDefinition beanDefinition, Object[] args) {
Object bean = null;
try {
// 判断是否返回代理 Bean 对象
bean = resolveBeforeInstantiation(beanName, beanDefinition);
if (null != bean) {
return bean;
}
// 实例化Bean
bean = createBeanInstance(beanDefinition, beanName, args);
// 实例化后判断
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
if (beanDefinition.isSingleton()) {
registerSingletonBean(beanName, bean);
}
return bean;
}
/**
* Bean 实例化后对于返回 false 的对象,不再执行后续设置 Bean 对象属性的操作
*
* @param beanName 对象名称
* @param bean 对象
* @return 布尔值
*/
private boolean applyBeanPostProcessorsAfterInstantiation(String beanName, Object bean) {
boolean continueWithPropertyPopulation = true;
for (BeanPostProcessor beanPostProcessor : getBeanPostProcessors()) {
if (beanPostProcessor instanceof InstantiationAwareBeanPostProcessor) {
InstantiationAwareBeanPostProcessor instantiationAwareBeanPostProcessor = (InstantiationAwareBeanPostProcessor) beanPostProcessor;
if (!instantiationAwareBeanPostProcessor.postProcessAfterInstantiation(bean, beanName)) {
continueWithPropertyPopulation = false;
break;
}
}
}
return continueWithPropertyPopulation;
}
...
private 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;
}
...
}
AbstractAutowireCapableBeanFactory#createBean
方法中,关注点在于 initializeBean -> applyBeanPostProcessorsAfterInitialization
这块逻辑的调用,最终完成 AOP 代理对象的创建操作。UserService.java
package com.lino.springframework.test.bean;
import com.lino.springframework.beans.factory.annotation.Autowired;
import com.lino.springframework.beans.factory.annotation.Value;
import com.lino.springframework.stereotype.Component;
import java.util.Random;
/**
* @description: 用户接口实现类
*/
public class UserService implements IUserService {
private String token;
@Override
public String queryUserInfo() {
try {
Thread.sleep(new Random(1).nextInt(100));
} catch (InterruptedException e) {
e.printStackTrace();
}
return "张三,10001,杭州," + token;
}
@Override
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;
}
}
UserServiceBeforeAdvice.java
package com.lino.springframework.test.bean;
import com.lino.springframework.aop.MethodBeforeAdvice;
import java.lang.reflect.Method;
/**
* @description: 用户前置处理
*/
public class UserServiceBeforeAdvice implements MethodBeforeAdvice {
@Override
public void before(Method method, Object[] args, Object target) throws Throwable {
System.out.println("拦截方法:" + method.getName());
}
}
spring.xml
<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="userService" class="com.lino.springframework.test.bean.UserService">
<property name="token" value="RejDlI78hu223Opo983Ds"/>
bean>
<bean class="com.lino.springframework.aop.framework.autoproxy.DefaultAdvisorAutoProxyCreator"/>
<bean id="beforeAdvice" class="com.lino.springframework.test.bean.UserServiceBeforeAdvice"/>
<bean id="methodInterceptor" class="com.lino.springframework.aop.framework.adapter.MethodBeforeAdviceInterceptor">
<property name="advice" ref="beforeAdvice"/>
bean>
<bean id="pointcutAdvisor" class="com.lino.springframework.aop.aspectj.AspectJExpressionPointcutAdvisor">
<property name="expression" value="execution(* com.lino.springframework.test.bean.IUserService.*(..))"/>
<property name="advice" ref="methodInterceptor"/>
bean>
beans>
ApiTest.java
@Test
public void test_autoProxy() {
ClassPathXmlApplicationContext applicationContext = new ClassPathXmlApplicationContext("classpath:spring.xml");
IUserService userService = applicationContext.getBean("userService", IUserService.class);
System.out.println("测试结果:" + userService.queryUserInfo());
}
测试结果
拦截方法:queryUserInfo
测试结果:张三,10001,杭州,RejDlI78hu223Opo983Ds
CglibSubclassingInstantiationStrategy
、SimpleInstantiationStrategy
。