spring手写源码一

分为三个包

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);
    }


}

 

  • 1
    点赞
  • 3
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值