Skip to content

Commit

Permalink
Merge pull request #3 from kerwin89/populate-proxy-bean-with-property…
Browse files Browse the repository at this point in the history
…-values

为AOP代理对象注入属性
  • Loading branch information
DerekYRC committed Dec 30, 2020
2 parents f90b1d2 + 9e2b1e4 commit 8c1e6fe
Show file tree
Hide file tree
Showing 6 changed files with 100 additions and 68 deletions.
51 changes: 51 additions & 0 deletions changelog.md
Original file line number Diff line number Diff line change
Expand Up @@ -1121,7 +1121,58 @@ public class AutowiredAnnotationTest {
}
}
```
## 为代理bean填充属性
> 分支: populate-proxy-bean-with-property-values
DefaultAdvisorAutoProxyCreator#postProcessBeforeInstantiation的内容挪到postProcessAfterInitialization方法中, postProcessBeforeInstantiation返回null

用bean接受AbstractAutowireCapableBeanFactory#initializeBean的返回值

```
<?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="worldService" class="org.springframework.test.service.WorldServiceImpl">
<property name="name" value="earth"/>
</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.service.WorldService.explode(..))"/>
<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.WorldServiceBeforeAdvice"/>
</beans>
```
```
public class AutoProxyTest {
@Test
public void testAutoProxy() throws Exception {
ClassPathXmlApplicationContext applicationContext = new ClassPathXmlApplicationContext("classpath:auto-proxy.xml");
//获取代理对象
WorldService worldService = applicationContext.getBean("worldService", WorldService.class);
worldService.explode();
WorldService worldService1 = applicationContext.getBean("worldService", WorldService.class);
assertThat(worldService == worldService1).isTrue();
}
}
```



Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -9,7 +9,6 @@
import org.springframework.beans.PropertyValues;
import org.springframework.beans.factory.BeanFactory;
import org.springframework.beans.factory.BeanFactoryAware;
import org.springframework.beans.factory.config.BeanDefinition;
import org.springframework.beans.factory.config.InstantiationAwareBeanPostProcessor;
import org.springframework.beans.factory.support.DefaultListableBeanFactory;

Expand All @@ -25,32 +24,7 @@ public class DefaultAdvisorAutoProxyCreator implements InstantiationAwareBeanPos

@Override
public Object postProcessBeforeInstantiation(Class<?> beanClass, String beanName) throws BeansException {
//避免死循环
if (isInfrastructureClass(beanClass)) {
return null;
}

Collection<AspectJExpressionPointcutAdvisor> advisors = beanFactory.getBeansOfType(AspectJExpressionPointcutAdvisor.class).values();
try {
for (AspectJExpressionPointcutAdvisor advisor : advisors) {
ClassFilter classFilter = advisor.getPointcut().getClassFilter();
if (classFilter.matches(beanClass)) {
AdvisedSupport advisedSupport = new AdvisedSupport();

BeanDefinition beanDefinition = beanFactory.getBeanDefinition(beanName);
Object bean = beanFactory.getInstantiationStrategy().instantiate(beanDefinition);
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 null;
}

Expand All @@ -72,6 +46,29 @@ public Object postProcessBeforeInitialization(Object bean, String beanName) thro

@Override
public Object postProcessAfterInitialization(Object bean, String beanName) throws BeansException {
//避免死循环
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;
}

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -24,43 +24,10 @@ public abstract class AbstractAutowireCapableBeanFactory extends AbstractBeanFac

@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 = null;
try {
Expand All @@ -70,7 +37,7 @@ protected Object doCreateBean(String beanName, BeanDefinition beanDefinition) {
//为bean填充属性
applyPropertyValues(beanName, bean, beanDefinition);
//执行bean的初始化方法和BeanPostProcessor的前置和后置处理方法
initializeBean(beanName, bean, beanDefinition);
bean = initializeBean(beanName, bean, beanDefinition);
} catch (Exception e) {
throw new BeansException("Instantiation of bean failed", e);
}
Expand Down Expand Up @@ -170,7 +137,7 @@ protected Object initializeBean(String beanName, Object bean, BeanDefinition bea
}

//执行BeanPostProcessor的后置处理
wrappedBean = applyBeanPostProcessorsAfterInitialization(bean, beanName);
wrappedBean = applyBeanPostProcessorsAfterInitialization(wrappedBean, beanName);
return wrappedBean;
}

Expand All @@ -181,7 +148,7 @@ public Object applyBeanPostProcessorsBeforeInitialization(Object existingBean, S
for (BeanPostProcessor processor : getBeanPostProcessors()) {
Object current = processor.postProcessBeforeInitialization(result, beanName);
if (current == null) {
return result;
continue;
}
result = current;
}
Expand All @@ -196,7 +163,7 @@ public Object applyBeanPostProcessorsAfterInitialization(Object existingBean, St
for (BeanPostProcessor processor : getBeanPostProcessors()) {
Object current = processor.postProcessAfterInitialization(result, beanName);
if (current == null) {
return result;
continue;
}
result = current;
}
Expand Down
4 changes: 4 additions & 0 deletions src/test/java/org/springframework/test/aop/AutoProxyTest.java
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,8 @@
import org.springframework.context.support.ClassPathXmlApplicationContext;
import org.springframework.test.service.WorldService;

import static org.assertj.core.api.Assertions.assertThat;

/**
* @author derekyi
* @date 2020/12/6
Expand All @@ -17,5 +19,7 @@ public void testAutoProxy() throws Exception {
//获取代理对象
WorldService worldService = applicationContext.getBean("worldService", WorldService.class);
worldService.explode();
WorldService worldService1 = applicationContext.getBean("worldService", WorldService.class);
assertThat(worldService == worldService1).isTrue();
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -6,8 +6,19 @@
*/
public class WorldServiceImpl implements WorldService {

@Override
public void explode() {
System.out.println("The Earth is going to explode");
}
private String name;

public String getName() {
return name;
}

public void setName(String name) {
this.name = name;
}

@Override
public void explode() {
System.out.println("The Earth is going to explode");
System.out.println("name: " + getName());
}
}
4 changes: 3 additions & 1 deletion src/test/resources/auto-proxy.xml
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,9 @@
http://www.springframework.org/schema/context
http://www.springframework.org/schema/context/spring-context-4.0.xsd">

<bean id="worldService" class="org.springframework.test.service.WorldServiceImpl"/>
<bean id="worldService" class="org.springframework.test.service.WorldServiceImpl">
<property name="name" value="earth"/>
</bean>

<bean class="org.springframework.aop.framework.autoproxy.DefaultAdvisorAutoProxyCreator"/>

Expand Down

0 comments on commit 8c1e6fe

Please sign in to comment.