Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

为AOP代理对象注入属性 #3

Merged
merged 1 commit into from
Dec 30, 2020
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
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