Skip to content

Commit

Permalink
支持懒加载和多切面增强
Browse files Browse the repository at this point in the history
  • Loading branch information
DerekYRC committed Dec 26, 2022
1 parent 15f0b25 commit 277afdc
Show file tree
Hide file tree
Showing 19 changed files with 151 additions and 119 deletions.
2 changes: 0 additions & 2 deletions changelog.md
Original file line number Diff line number Diff line change
Expand Up @@ -1926,5 +1926,3 @@ AfterAdvice: do something after the earth explodes
```

至此,我们已经解决多切面匹配同一方法的问题。

## <p align="center">====================不容易啊,完美撒花====================</p>
2 changes: 2 additions & 0 deletions src/main/java/org/springframework/aop/AfterAdvice.java
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,8 @@
import org.aopalliance.aop.Advice;

/**
* 后置增强
*
* @author zqc
* @date 2022/12/16
*/
Expand Down
Original file line number Diff line number Diff line change
@@ -1,13 +1,14 @@
package org.springframework.aop;

import org.springframework.aop.AfterAdvice;

import java.lang.reflect.Method;

/**
* 后置增强
*
* @author zqc
* @date 2022/12/16
*/
public interface AfterReturningAdvice extends AfterAdvice {

void afterReturning( Object returnValue, Method method, Object[] args, Object target) throws Throwable;
}
Original file line number Diff line number Diff line change
Expand Up @@ -12,6 +12,6 @@
public interface AdvisorChainFactory {


List<Object> getInterceptorsAndDynamicInterceptionAdvice(AdvisedSupport config, Method method, Class<?> targetClass);
List<Object> getInterceptorsAndDynamicInterceptionAdvice(AdvisedSupport config, Method method, Class<?> targetClass);

}
24 changes: 15 additions & 9 deletions src/main/java/org/springframework/aop/framework/CglibAopProxy.java
Original file line number Diff line number Diff line change
@@ -1,14 +1,17 @@
package org.springframework.aop.framework;

import java.lang.reflect.Method;
import java.util.List;

import net.sf.cglib.proxy.Enhancer;
import net.sf.cglib.proxy.MethodInterceptor;
import net.sf.cglib.proxy.MethodProxy;
import org.springframework.aop.AdvisedSupport;

import java.lang.reflect.Method;
import java.util.List;
import org.springframework.aop.AdvisedSupport;

/**
* cglib动态代理
*
* @author zqc
* @date 2022/12/17
*/
Expand Down Expand Up @@ -45,14 +48,17 @@ private DynamicAdvisedInterceptor(AdvisedSupport advised) {
@Override
public Object intercept(Object proxy, Method method, Object[] args, MethodProxy methodProxy) throws Throwable {
// 获取目标对象
Object target=advised.getTargetSource().getTarget();
Object target = advised.getTargetSource().getTarget();
Class<?> targetClass = target.getClass();
Object retVal = null;
List<Object> chain = this.advised.getInterceptorsAndDynamicInterceptionAdvice(method, targetClass);
CglibMethodInvocation methodInvocation = new CglibMethodInvocation(proxy, target, method, args, targetClass, chain, methodProxy);
if(chain==null||chain.isEmpty()){
retVal =methodProxy.invoke(target, args);
}else retVal=methodInvocation.proceed();
if (chain == null || chain.isEmpty()) {
//代理方法
retVal = methodProxy.invoke(target, args);
} else {
retVal = methodInvocation.proceed();
}
return retVal;
}
}
Expand All @@ -62,8 +68,8 @@ private static class CglibMethodInvocation extends ReflectiveMethodInvocation {
private final MethodProxy methodProxy;

public CglibMethodInvocation(Object proxy, Object target, Method method,
Object[] arguments, Class<?> targetClass,
List<Object> interceptorsAndDynamicMethodMatchers, MethodProxy methodProxy) {
Object[] arguments, Class<?> targetClass,
List<Object> interceptorsAndDynamicMethodMatchers, MethodProxy methodProxy) {
super(proxy, target, method, arguments, targetClass, interceptorsAndDynamicMethodMatchers);
this.methodProxy = methodProxy;
}
Expand Down
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
package org.springframework.aop.framework;

import org.aopalliance.intercept.MethodInterceptor;

import org.springframework.aop.AdvisedSupport;
import org.springframework.aop.Advisor;
import org.springframework.aop.MethodMatcher;
Expand All @@ -15,28 +16,29 @@
* @date 2022/12/17
*/
public class DefaultAdvisorChainFactory implements AdvisorChainFactory {
@Override
public List<Object> getInterceptorsAndDynamicInterceptionAdvice(AdvisedSupport config, Method method, Class<?> targetClass) {
Advisor[] advisors = config.getAdvisors().toArray(new Advisor[0]);
List<Object> interceptorList = new ArrayList<>(advisors.length);
Class<?> actualClass = (targetClass != null ? targetClass : method.getDeclaringClass());
for (Advisor advisor : advisors) {
if (advisor instanceof PointcutAdvisor) {
// Add it conditionally.
PointcutAdvisor pointcutAdvisor = (PointcutAdvisor) advisor;
// 校验当前Advisor是否适用于当前对象
if (pointcutAdvisor.getPointcut().getClassFilter().matches(actualClass)) {
MethodMatcher mm = pointcutAdvisor.getPointcut().getMethodMatcher();
boolean match;
// 校验Advisor是否应用到当前方法上
match = mm.matches(method,actualClass);
if (match) {
MethodInterceptor interceptor = (MethodInterceptor) advisor.getAdvice();
interceptorList.add(interceptor);
}
}
}
}
return interceptorList;
}

@Override
public List<Object> getInterceptorsAndDynamicInterceptionAdvice(AdvisedSupport config, Method method, Class<?> targetClass) {
Advisor[] advisors = config.getAdvisors().toArray(new Advisor[0]);
List<Object> interceptorList = new ArrayList<>(advisors.length);
Class<?> actualClass = (targetClass != null ? targetClass : method.getDeclaringClass());
for (Advisor advisor : advisors) {
if (advisor instanceof PointcutAdvisor) {
// Add it conditionally.
PointcutAdvisor pointcutAdvisor = (PointcutAdvisor) advisor;
// 校验当前Advisor是否适用于当前对象
if (pointcutAdvisor.getPointcut().getClassFilter().matches(actualClass)) {
MethodMatcher mm = pointcutAdvisor.getPointcut().getMethodMatcher();
boolean match;
// 校验Advisor是否应用到当前方法上
match = mm.matches(method, actualClass);
if (match) {
MethodInterceptor interceptor = (MethodInterceptor) advisor.getAdvice();
interceptorList.add(interceptor);
}
}
}
}
return interceptorList;
}
}
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
package org.springframework.aop.framework;

import org.aopalliance.intercept.MethodInvocation;

import org.springframework.aop.AdvisedSupport;

import java.lang.reflect.InvocationHandler;
Expand Down Expand Up @@ -35,14 +36,14 @@ public Object getProxy() {
@Override
public Object invoke(Object proxy, Method method, Object[] args) throws Throwable {
// 获取目标对象
Object target=advised.getTargetSource().getTarget();
Object target = advised.getTargetSource().getTarget();
Class<?> targetClass = target.getClass();
Object retVal = null;
// 获取拦截器链
List<Object> chain = this.advised.getInterceptorsAndDynamicInterceptionAdvice(method, targetClass);
if(chain==null||chain.isEmpty()){
if (chain == null || chain.isEmpty()) {
return method.invoke(target, args);
}else{
} else {
// 将拦截器统一封装成ReflectiveMethodInvocation
MethodInvocation invocation =
new ReflectiveMethodInvocation(proxy, target, method, args, targetClass, chain);
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,7 @@
* @author zqc
* @date 2022/12/16
*/
public class ProxyFactory extends AdvisedSupport{
public class ProxyFactory extends AdvisedSupport {


public ProxyFactory() {
Expand All @@ -17,9 +17,10 @@ public Object getProxy() {
}

private AopProxy createAopProxy() {
if (this.isProxyTargetClass()||this.getTargetSource().getTargetClass().length==0) {
if (this.isProxyTargetClass() || this.getTargetSource().getTargetClass().length == 0) {
return new CglibAopProxy(this);
}

return new JdkDynamicAopProxy(this);
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -2,29 +2,32 @@

import org.aopalliance.intercept.MethodInterceptor;
import org.aopalliance.intercept.MethodInvocation;

import org.springframework.aop.AfterAdvice;
import org.springframework.aop.AfterReturningAdvice;

/**
* 后置增强拦截器
*
* @author zqc
* @date 2022/12/20
*/
public class AfterReturningAdviceInterceptor implements MethodInterceptor, AfterAdvice {

private AfterReturningAdvice advice;
private AfterReturningAdvice advice;

public AfterReturningAdviceInterceptor() {
}
public AfterReturningAdviceInterceptor() {
}

public AfterReturningAdviceInterceptor(AfterReturningAdvice advice) {
this.advice = advice;
}
public AfterReturningAdviceInterceptor(AfterReturningAdvice advice) {
this.advice = advice;
}


@Override
public Object invoke(MethodInvocation mi) throws Throwable {
Object retVal = mi.proceed();
this.advice.afterReturning(retVal, mi.getMethod(), mi.getArguments(), mi.getThis());
return retVal;
}
@Override
public Object invoke(MethodInvocation mi) throws Throwable {
Object retVal = mi.proceed();
this.advice.afterReturning(retVal, mi.getMethod(), mi.getArguments(), mi.getThis());
return retVal;
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -26,6 +26,7 @@ public void setAdvice(MethodBeforeAdvice advice) {

@Override
public Object invoke(MethodInvocation mi) throws Throwable {
//在执行被代理方法之前,先执行before advice操作
this.advice.before(mi.getMethod(), mi.getArguments(), mi.getThis());
return mi.proceed();
}
Expand Down
Original file line number Diff line number Diff line change
@@ -1,8 +1,15 @@
package org.springframework.aop.framework.autoproxy;

import java.util.Collection;
import java.util.HashSet;
import java.util.Set;

import org.aopalliance.aop.Advice;
import org.aopalliance.intercept.MethodInterceptor;
import org.springframework.aop.*;

import org.springframework.aop.Advisor;
import org.springframework.aop.ClassFilter;
import org.springframework.aop.Pointcut;
import org.springframework.aop.TargetSource;
import org.springframework.aop.aspectj.AspectJExpressionPointcutAdvisor;
import org.springframework.aop.framework.ProxyFactory;
import org.springframework.beans.BeansException;
Expand All @@ -12,10 +19,6 @@
import org.springframework.beans.factory.config.InstantiationAwareBeanPostProcessor;
import org.springframework.beans.factory.support.DefaultListableBeanFactory;

import java.util.Collection;
import java.util.HashSet;
import java.util.Set;

/**
* @author derekyi
* @date 2020/12/6
Expand Down Expand Up @@ -47,7 +50,8 @@ protected Object wrapIfNecessary(Object bean, String beanName) {
return bean;
}

Collection<AspectJExpressionPointcutAdvisor> advisors = beanFactory.getBeansOfType(AspectJExpressionPointcutAdvisor.class).values();
Collection<AspectJExpressionPointcutAdvisor> advisors = beanFactory.getBeansOfType(AspectJExpressionPointcutAdvisor.class)
.values();
try {
ProxyFactory proxyFactory = new ProxyFactory();
for (AspectJExpressionPointcutAdvisor advisor : advisors) {
Expand All @@ -59,7 +63,9 @@ protected Object wrapIfNecessary(Object bean, String beanName) {
proxyFactory.setMethodMatcher(advisor.getPointcut().getMethodMatcher());
}
}
if(!proxyFactory.getAdvisors().isEmpty()) return proxyFactory.getProxy();
if (!proxyFactory.getAdvisors().isEmpty()) {
return proxyFactory.getProxy();
}
} catch (Exception ex) {
throw new BeansException("Error create proxy bean for: " + beanName, ex);
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -71,10 +71,10 @@ public String[] getBeanDefinitionNames() {
}

@Override
//只有当bean是单例且不为懒加载才会被创建
public void preInstantiateSingletons() throws BeansException {
beanDefinitionMap.forEach((beanName, beanDefinition) -> {
if(beanDefinition.isSingleton()&&!beanDefinition.isLazyInit()){
//只有当bean是单例且不为懒加载才会被创建
if (beanDefinition.isSingleton() && !beanDefinition.isLazyInit()) {
getBean(beanName);
}
});
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,7 @@
import org.dom4j.DocumentException;
import org.dom4j.Element;
import org.dom4j.io.SAXReader;

import org.springframework.beans.BeansException;
import org.springframework.beans.PropertyValue;
import org.springframework.beans.factory.config.BeanDefinition;
Expand Down Expand Up @@ -95,7 +96,7 @@ protected void doLoadBeanDefinitions(InputStream inputStream) throws DocumentExc
String initMethodName = bean.attributeValue(INIT_METHOD_ATTRIBUTE);
String destroyMethodName = bean.attributeValue(DESTROY_METHOD_ATTRIBUTE);
String beanScope = bean.attributeValue(SCOPE_ATTRIBUTE);
String lazyInit=bean.attributeValue(LAZYINIT_ATTRIBUTE);
String lazyInit = bean.attributeValue(LAZYINIT_ATTRIBUTE);
Class<?> clazz;
try {
clazz = Class.forName(className);
Expand All @@ -112,7 +113,7 @@ protected void doLoadBeanDefinitions(InputStream inputStream) throws DocumentExc
BeanDefinition beanDefinition = new BeanDefinition(clazz);
beanDefinition.setInitMethodName(initMethodName);
beanDefinition.setDestroyMethodName(destroyMethodName);
beanDefinition.setLazyInit("true".equals(lazyInit));
beanDefinition.setLazyInit(Boolean.parseBoolean(lazyInit));
if (StrUtil.isNotEmpty(beanScope)) {
beanDefinition.setScope(beanScope);
}
Expand Down
Loading

0 comments on commit 277afdc

Please sign in to comment.