分为三个包
aop包、bean包、samples包
aop包含advice、advisor、pointcut和各个类
advice包
Advice类
package com.lv.spring.aop.advice;
/**
* Created by lvyanghui
* 2018/12/25 14:38
*/
public interface Advice {
}
AfterReturningAdvice类
package com.lv.spring.aop.advice;
import java.lang.reflect.Method;
/**
* Created by lvyanghui
* 2018/12/25 14:41
*/
public interface AfterReturningAdvice extends Advice{
void afterReturing(Object returnValue, Method method, Object[] args,Object target);
}
MethodBeforeAdvice类
package com.lv.spring.aop.advice;
import java.lang.reflect.Method;
/**
* Created by lvyanghui
* 2018/12/25 14:41
*/
public interface MethodBeforeAdvice extends Advice{
void beforeMethod(Method method, Object[] args, Object target);
}
MethodInterceptor类
package com.lv.spring.aop.advice;
import java.lang.reflect.Method;
/**
* Created by lvyanghui
* 2018/12/25 14:41
*/
public interface MethodInterceptor extends Advice{
Object invoke(Method method, Object[] args, Object target) throws Exception;
}
advisor包
Advisor类
package com.lv.spring.aop.advisor;
/**
* Created by lvyanghui
* 2018/12/25 15:07
*/
public interface Advisor {
String getAdviceBeanName();
String getExpression();
}
AdvisorRegistry类
package com.lv.spring.aop.advisor;
import java.util.List;
/**
* Created by lvyanghui
* 2018/12/25 15:07
*/
public interface AdvisorRegistry {
void registryAdvisor(Advisor advisor);
List<Advisor> getAdvisors();
}
AspectJPointCutAdvisor类
package com.lv.spring.aop.advisor;
import com.lv.spring.aop.pointcut.AspectJExpressionPointcut;
import com.lv.spring.aop.pointcut.Pointcut;
/**
* Created by lvyanghui
* 2018/12/27 11:03
*/
public class AspectJPointCutAdvisor implements Advisor,PointCutAdvisor{
private String expression;
private String adviceBeanName;
private Pointcut pointcut;
public AspectJPointCutAdvisor(String expression, String adviceBeanName) {
this.expression = expression;
this.adviceBeanName = adviceBeanName;
pointcut = new AspectJExpressionPointcut(expression);
}
@Override
public Pointcut getPointcut() {
return pointcut;
}
@Override
public String getAdviceBeanName() {
return adviceBeanName;
}
@Override
public String getExpression() {
return expression;
}
}
PointCutAdvisor类
package com.lv.spring.aop.advisor;
import com.lv.spring.aop.pointcut.Pointcut;
/**
* Created by lvyanghui
* 2018/12/26 11:10
*/
public interface PointCutAdvisor extends Advisor{
Pointcut getPointcut();
}
pointcut包
AspectJExpressionPointcut类
package com.lv.spring.aop.pointcut;
import org.aspectj.weaver.tools.PointcutExpression;
import org.aspectj.weaver.tools.PointcutParser;
import org.aspectj.weaver.tools.ShadowMatch;
import java.lang.reflect.Method;
/**
* Created by lvyanghui
* 2018/12/26 10:48
*/
public class AspectJExpressionPointcut implements Pointcut {
private PointcutParser parser = PointcutParser.getPointcutParserSupportingAllPrimitivesAndUsingContextClassloaderForResolution();
private String expression;
private PointcutExpression pointcutExpression;
public AspectJExpressionPointcut(String expression) {
this.expression = expression;
pointcutExpression = parser.parsePointcutExpression(expression);
}
public String getExpression() {
return expression;
}
public void setExpression(String expression) {
this.expression = expression;
}
public PointcutExpression getPointcutExpression() {
return pointcutExpression;
}
public void setPointcutExpression(PointcutExpression pointcutExpression) {
this.pointcutExpression = pointcutExpression;
}
@Override
public boolean matchsClass(Class<?> targetClass) {
return pointcutExpression.couldMatchJoinPointsInType(targetClass);
}
@Override
public boolean matchsMethod(Method method, Class<?> targetClass) {
ShadowMatch shadowMatch = pointcutExpression.matchesMethodExecution(method);
return shadowMatch.alwaysMatches();
}
}
Pointcut类
package com.lv.spring.aop.pointcut;
import java.lang.reflect.Method;
/**
* Created by lvyanghui
* 2018/12/25 14:47
*/
public interface Pointcut {
boolean matchsClass(Class<?> targetClass);
boolean matchsMethod(Method method, Class<?> targetClass);
}
aop包下的各个类
AdvisorAutoProxyCreator类
package com.lv.spring.aop;
import com.lv.spring.aop.advisor.Advisor;
import com.lv.spring.aop.advisor.AdvisorRegistry;
import com.lv.spring.aop.advisor.PointCutAdvisor;
import com.lv.spring.aop.pointcut.Pointcut;
import com.lv.spring.bean.BeanFactory;
import com.lv.spring.bean.BeanFactoryAware;
import com.lv.spring.bean.BeanPostProcessor;
import org.apache.commons.collections4.CollectionUtils;
import org.springframework.util.ClassUtils;
import org.springframework.util.ReflectionUtils;
import java.lang.reflect.Method;
import java.util.ArrayList;
import java.util.List;
import java.util.Set;
/**
* Created by lvyanghui
* 2018/12/27 14:56
*/
public class AdvisorAutoProxyCreator implements AdvisorRegistry,BeanPostProcessor,BeanFactoryAware{
private List<Advisor> advisors = new ArrayList<Advisor>();
private BeanFactory beanFactory;
@Override
public void registryAdvisor(Advisor advisor) {
advisors.add(advisor);
}
@Override
public List<Advisor> getAdvisors() {
return advisors;
}
@Override
public void setBeanFactory(BeanFactory beanFactory) {
this.beanFactory = beanFactory;
}
@Override
public Object postProcessAfterInitialization(String beanName, Object bean) {
List<Advisor> matchsAdvisors = getMatchsAdvisor(beanName,bean);
if(CollectionUtils.isNotEmpty(matchsAdvisors)){
bean = createProxy(beanName, bean, matchsAdvisors);
}
return bean;
}
public List<Advisor> getMatchsAdvisor(String beanName, Object bean){
List<Advisor> matchsAdvisors = new ArrayList<Advisor>();
Class beanClass = bean.getClass();
List<Method> allMethods = getAllMethodForClass(beanClass);
for(Advisor advisor : advisors){
if(advisor instanceof PointCutAdvisor){
if(isPointcutMatchBean((PointCutAdvisor)advisor,beanClass,allMethods)){
matchsAdvisors.add(advisor);
}
}
}
return matchsAdvisors;
}
public List<Method> getAllMethodForClass(Class beanClass){
List<Method> allMethods = new ArrayList<>();
Set<Class<?>> classes = ClassUtils.getAllInterfacesForClassAsSet(beanClass);
classes.add(beanClass);
for(Class clazz : classes){
Method[] allDeclaredMethods = ReflectionUtils.getAllDeclaredMethods(clazz);
for(Method method : allDeclaredMethods){
allMethods.add(method);
}
}
return allMethods;
}
public boolean isPointcutMatchBean(PointCutAdvisor pa, Class clazz, List<Method> allMethods){
Pointcut pointcut = pa.getPointcut();
if(!pointcut.matchsClass(clazz)){
return false;
}
for(Method method : allMethods){
if(pointcut.matchsMethod(method,clazz)){
return true;
}
}
return false;
}
public Object createProxy(String beanName, Object bean, List<Advisor> matchsAdvisors){
AopProxy aopProxy = AopProxyFactory.getDefaultAopProxyFactory().createAopProxy(beanName, bean, matchsAdvisors, beanFactory);
return aopProxy.getProxy();
}
}
AopAdviceChainInvocation类
package com.lv.spring.aop;
import com.lv.spring.aop.advice.Advice;
import com.lv.spring.aop.advice.AfterReturningAdvice;
import com.lv.spring.aop.advice.MethodInterceptor;
import com.lv.spring.aop.advice.MethodBeforeAdvice;
import java.lang.reflect.Method;
import java.util.List;
/**
* Created by lvyanghui
* 2018/12/27 16:12
*/
public class AopAdviceChainInvocation {
private Object proxy;
private Object target;
private Method method;
private Object[] args;
private List<Advice> advices;
public AopAdviceChainInvocation(Object proxy, Object target, Method method, Object[] args, List<Advice> advices) {
this.proxy = proxy;
this.target = target;
this.method = method;
this.args = args;
this.advices = advices;
}
private int index = 0;
public Object doAdvice()throws Exception{
if(index == advices.size()){
return method.invoke(target,args);
}
Advice advice = advices.get(index++);
if(advice instanceof MethodBeforeAdvice){
((MethodBeforeAdvice) advice).beforeMethod(method,args,target);
}else if(advice instanceof MethodInterceptor){
Method doAdviceMethod = this.getClass().getMethod("doAdvice", null);
return ((MethodInterceptor) advice).invoke(doAdviceMethod, null, this);
}else if(advice instanceof AfterReturningAdvice){
Object returnValue = doAdvice();
((AfterReturningAdvice) advice).afterReturing(returnValue, method, args, target);
return returnValue;
}
return this.doAdvice();
}
}
AopProxy类
package com.lv.spring.aop;
/**
* Created by lvyanghui
* 2018/12/27 11:14
*/
public interface AopProxy {
Object getProxy();
Object getProxy(ClassLoader classLoader);
}
AopProxyFactory类
package com.lv.spring.aop;
import com.lv.spring.aop.advisor.Advisor;
import com.lv.spring.bean.BeanFactory;
import java.util.List;
/**
* Created by lvyanghui
* 2018/12/27 11:13
*/
public interface AopProxyFactory {
AopProxy createAopProxy(String beanName, Object bean, List<Advisor> advisors, BeanFactory beanFactory);
static AopProxyFactory getDefaultAopProxyFactory(){
return new DefaultAopProxyFactory();
}
}
AopProxyUtils类
package com.lv.spring.aop;
import com.lv.spring.aop.advice.Advice;
import com.lv.spring.aop.advisor.Advisor;
import com.lv.spring.aop.advisor.PointCutAdvisor;
import com.lv.spring.bean.BeanFactory;
import org.apache.commons.collections4.CollectionUtils;
import java.lang.reflect.Method;
import java.util.ArrayList;
import java.util.List;
/**
* Created by lvyanghui
* 2018/12/27 16:41
*/
public class AopProxyUtils {
public static Object doInvokeAdvice(Object proxy, Object target, Method method, Object[] args, List<Advisor> advisors, BeanFactory beanFactory)throws Exception{
List<Advice> advices = getMatchAdvices(advisors,method,target,beanFactory);
if(CollectionUtils.isEmpty(advices)){
return method.invoke(target,args);
}else{
AopAdviceChainInvocation chain = new AopAdviceChainInvocation(proxy,target,method,args,advices);
return chain.doAdvice();
}
}
public static List<Advice> getMatchAdvices(List<Advisor> advisors,Method method,Object target,BeanFactory beanFactory)throws Exception{
if(CollectionUtils.isEmpty(advisors)){
return null;
}
List<Advice> advices = new ArrayList<>();
for(Advisor advisor : advisors){
if(advisor instanceof PointCutAdvisor){
if(((PointCutAdvisor) advisor).getPointcut().matchsMethod(method,target.getClass())){
advices.add((Advice)beanFactory.getBean(advisor.getAdviceBeanName()));
}
}
}
return advices;
}
}
CglibDynamicAopProxy类
package com.lv.spring.aop;
import com.lv.spring.aop.advisor.Advisor;
import com.lv.spring.bean.BeanFactory;
import net.sf.cglib.proxy.Enhancer;
import net.sf.cglib.proxy.MethodInterceptor;
import net.sf.cglib.proxy.MethodProxy;
import java.lang.reflect.Method;
import java.util.List;
/**
* Created by lvyanghui
* 2018/12/27 11:33
*/
public class CglibDynamicAopProxy implements AopProxy,MethodInterceptor{
private static Enhancer enhancer = new Enhancer();
private String beanName;
private Object bean;
private List<Advisor> advisors;
private BeanFactory beanFactory;
public CglibDynamicAopProxy(String beanName, Object bean, List<Advisor> advisors, BeanFactory beanFactory) {
this.beanName = beanName;
this.bean = bean;
this.advisors = advisors;
this.beanFactory = beanFactory;
}
@Override
public Object getProxy() {
return getProxy(bean.getClass().getClassLoader());
}
@Override
public Object getProxy(ClassLoader classLoader) {
enhancer.setSuperclass(bean.getClass());
enhancer.setInterfaces(this.getClass().getInterfaces());
enhancer.setCallback(this);
return enhancer.create();
/*Constructor constructor = null;
try {
constructor = bean.getClass().getConstructor();
} catch (NoSuchMethodException e) {
}
if(null != constructor){
return enhancer.create();
}else{
BeanDefinition beanDefinition = ((DefaultBeanFactory) beanFactory).getBeanDefinition(beanName);
return enhancer.create(beanDefinition.getConstructor().getParameterTypes(),beanDefinition.getConstructorArgumentRealValues());
}*/
}
@Override
public Object intercept(Object proxy, Method method, Object[] args, MethodProxy methodProxy) throws Throwable {
return AopProxyUtils.doInvokeAdvice(proxy,bean,method,args,advisors,beanFactory);
}
}
DefaultAopProxyFactory类
package com.lv.spring.aop;
import com.lv.spring.aop.advisor.Advisor;
import com.lv.spring.bean.BeanFactory;
import java.util.List;
/**
* Created by lvyanghui
* 2018/12/27 11:22
*/
public class DefaultAopProxyFactory implements AopProxyFactory{
@Override
public AopProxy createAopProxy(String beanName, Object bean, List<Advisor> advisors, BeanFactory beanFactory) {
if(shouldUseJDKDynamicProxy(beanName,bean)){
return new JdkDynamicAopProxy(beanName,bean,advisors,beanFactory);
}else{
return new CglibDynamicAopProxy(beanName,bean,advisors,beanFactory);
}
}
public boolean shouldUseJDKDynamicProxy(String beanName, Object bean){
return false;
}
}
JdkDynamicAopProxy类
package com.lv.spring.aop;
import com.lv.spring.aop.advisor.Advisor;
import com.lv.spring.bean.BeanFactory;
import java.lang.reflect.InvocationHandler;
import java.lang.reflect.Method;
import java.lang.reflect.Proxy;
import java.util.List;
/**
* Created by lvyanghui
* 2018/12/27 11:23
*/
public class JdkDynamicAopProxy implements AopProxy,InvocationHandler {
private String beanName;
private Object bean;
private List<Advisor> advisors;
private BeanFactory beanFactory;
public JdkDynamicAopProxy(String beanName, Object bean, List<Advisor> advisors, BeanFactory beanFactory) {
this.beanName = beanName;
this.bean = bean;
this.advisors = advisors;
this.beanFactory = beanFactory;
}
@Override
public Object getProxy() {
return getProxy(bean.getClass().getClassLoader());
}
@Override
public Object getProxy(ClassLoader classLoader) {
return Proxy.newProxyInstance(classLoader,bean.getClass().getInterfaces(),this);
}
@Override
public Object invoke(Object proxy, Method method, Object[] args) throws Throwable {
return AopProxyUtils.doInvokeAdvice(proxy,bean,method,args,advisors,beanFactory);
}
}