【Spring学习】3.0手写spring-AOP

3.0手写spring-AOP

AOP分析

image

image

切面增强点切入点等功能

image

image

通知切点织入分析

image

Advice设计

image

前置增强

image

后置增强

image

环绕增强

image

Advice接口设计

image

PontCut设计

image

AspectJ表达式

aop:pointcut 的expression 的各种表达式

任意公共方法的执行:
execution(public * *(…))
任何一个以“set”开始的方法的执行:
execution(* set*(…))
AccountService 接口的任意方法的执行:
execution(* com.xyz.service.AccountService.*(…))
定义在service包里的任意方法的执行:
execution(* com.xyz.service.*.*(…))
定义在service包或者子包里的任意方法的执行:
execution(* com.xyz.service…*.*(…))
在service包里的任意连接点(在Spring AOP中只是方法执行) :
within(com.xyz.service.*)
在service包或者子包里的任意连接点(在Spring AOP中只是方法执行) :
within(com.xyz.service…*)
实现了 AccountService 接口的代理对象的任意连接点(在Spring AOP中只是方法执行) :
this(com.xyz.service.AccountService)
'this’在binding form中用的更多:- 请常见以下讨论通知的章节中关于如何使得代理对象可以在通知体内访问到的部分。
实现了 AccountService 接口的目标对象的任意连接点(在Spring AOP中只是方法执行) :
target(com.xyz.service.AccountService)
'target’在binding form中用的更多:- 请常见以下讨论通知的章节中关于如何使得目标对象可以在通知体内访问到的部分。
任何一个只接受一个参数,且在运行时传入的参数实现了 Serializable 接口的连接点 (在Spring AOP中只是方法执行)
args(java.io.Serializable)
'args’在binding form中用的更多:- 请常见以下讨论通知的章节中关于如何使得方法参数可以在通知体内访问到的部分。 请注意在例子中给出的切入点不同于 execution(* *(java.io.Serializable)): args只有在动态运行时候传入参数是可序列化的(Serializable)才匹配,而execution 在传入参数的签名声明的类型实现了 Serializable 接口时候匹配。
有一个 @Transactional 注解的目标对象中的任意连接点(在Spring AOP中只是方法执行)
@target(org.springframework.transaction.annotation.Transactional)
‘@target’ 也可以在binding form中使用:请常见以下讨论通知的章节中关于如何使得annotation对象可以在通知体内访问到的部分。
任何一个目标对象声明的类型有一个 @Transactional 注解的连接点(在Spring AOP中只是方法执行)
@within(org.springframework.transaction.annotation.Transactional)
'@within’也可以在binding form中使用:- 请常见以下讨论通知的章节中关于如何使得annotation对象可以在通知体内访问到的部分。
任何一个执行的方法有一个 @Transactional annotation的连接点(在Spring AOP中只是方法执行)
@annotation(org.springframework.transaction.annotation.Transactional)
‘@annotation’ 也可以在binding form中使用:- 请常见以下讨论通知的章节中关于如何使得annotation对象可以在通知体内访问到的部分。
任何一个接受一个参数,并且传入的参数在运行时的类型实现了 @Classified annotation的连接点(在Spring AOP中只是方法执行)
@args(com.xyz.security.Classified)

PointCut标准接口设计

image

public interface Pointcut {

	boolean matchsClass(Class<?> targetClass);

	boolean matchsMethod(Method method, Class<?> targetClass);
}
AspectJPointCut表达式

仅使用了Aspect J的切点表达式而已

以及表达式的解析

image

AspectJ的表达式实现

image

public class AspectJExpressionPointcut implements Pointcut {

	private static PointcutParser pp = PointcutParser
			.getPointcutParserSupportingAllPrimitivesAndUsingContextClassloaderForResolution();

	private String expression;

	private PointcutExpression pe;

	public AspectJExpressionPointcut(String expression) {
		super();
		this.expression = expression;
		pe = pp.parsePointcutExpression(expression);
	}

	@Override
	public boolean matchsClass(Class<?> targetClass) {
		return pe.couldMatchJoinPointsInType(targetClass);
	}

	@Override
	public boolean matchsMethod(Method method, Class<?> targetClass) {
		ShadowMatch sm = pe.matchesMethodExecution(method);
		return sm.alwaysMatches();
	}

Advisor: Advice PointCut的 使用

image

Advisor通知者用于Advice和Pointcut的组合

image

public interface Advisor {
	String getAdviceBeanName();
	String getExpression();
}
public interface PointcutAdvisor extends Advisor {
	Pointcut getPointcut();
}
public class AspectJPointcutAdvisor implements PointcutAdvisor {
	private String adviceBeanName;
	private String expression;
	private AspectJExpressionPointcut pointcut;
	public AspectJPointcutAdvisor(String adviceBeanName, String expression) {
		super();
		this.adviceBeanName = adviceBeanName;
		this.expression = expression;
		this.pointcut = new AspectJExpressionPointcut(this.expression);
	}
	@Override
	public Pointcut getPointcut() {
		return this.pointcut;
	}
	@Override
	public String   getAdviceBeanName() {
		return this.adviceBeanName;
	}
	@Override
	public String getExpression() {
		return this.expression;
	}
}
Adviosr的扩展

image

Weaving织入的分析

处于BeanFactory的过程。

image

观察者模式

image

BeanPostProcessor观察者模式的

image

public interface AdvisorRegistry {
	public void registAdvisor(Advisor ad);
	public List<Advisor> getAdvisors();
}

public interface BeanPostProcessor {
	default Object postProcessBeforeInitialization(Object bean, String beanName) throws Throwable {
		return bean;
	}
	default Object postProcessAfterInitialization(Object bean, String beanName) throws Throwable {
		return bean;
	}
}
public class AdvisorAutoProxyCreator implements AdvisorRegistry, BeanPostProcessor, BeanFactoryAware {
...
	private List<Advisor> advisors;
        public void registAdvisor(Advisor ad) {
		this.advisors.add(ad);
	}

	public Object postProcessAfterInitialization(Object bean, String beanName) throws Throwable {

		// 在此判断bean是否需要进行切面增强
		List<Advisor> matchAdvisors = getMatchedAdvisors(bean, beanName);
		// 如需要就进行增强,再返回增强的对象。
		if (CollectionUtils.isNotEmpty(matchAdvisors)) {
			bean = this.createProxy(bean, beanName, matchAdvisors);
		}
		return bean;
	}
...
}

public interface BeanFactory {
	/**
	 * 获取bean
	 * @param name
           bean的名字
	 * @return bean 实例
	 */
	Object getBean(String name) throws Throwable;

	void registerBeanPostProcessor(BeanPostProcessor bpp);
}
public class DefaultBeanFactory implements BeanFactory, BeanDefinitionRegistry, Closeable {

	private List<BeanPostProcessor> beanPostProcessors = Collections.synchronizedList(new ArrayList<>());
	@Override
	public void registerBeanPostProcessor(BeanPostProcessor bpp) {
		this.beanPostProcessors.add(bpp);
		if (bpp instanceof BeanFactoryAware) {
			((BeanFactoryAware) bpp).setBeanFactory(this);
		}
	}

	protected Object doGetBean(String beanName) throws Throwable {
                ...
		// 应用bean初始化前的处理
		instance = this.applyPostProcessBeforeInitialization(instance, beanName);

		// 执行初始化方法
		this.doInit(bd, instance);

		// 应用bean初始化后的处理
		instance = this.applyPostProcessAfterInitialization(instance, beanName);
        ...
        }
...
}

Weaving织入的实现

image

Class获取的信息
获取该类及其父类中所有公共(public)方法的数组。
    @CallerSensitive
    public Method[] getMethods() throws SecurityException {
        checkMemberAccess(Member.PUBLIC, Reflection.getCallerClass(), true);
        return copyMethods(privateGetPublicMethods());
    }
获取该类中指定名称和参数类型的声明方法(包括私有方法)。
    @CallerSensitive
    public Method getDeclaredMethod(String name, Class<?>... parameterTypes)
        throws NoSuchMethodException, SecurityException {
        checkMemberAccess(Member.DECLARED, Reflection.getCallerClass(), true);
        Method method = searchMethods(privateGetDeclaredMethods(false), name, parameterTypes);
        if (method == null) {
            throw new NoSuchMethodException(getName() + "." + name + argumentTypesToString(parameterTypes));
        }
        return method;
    }
判断代理增强
	public Object postProcessAfterInitialization(Object bean, String beanName) throws Throwable {

		// 在此判断bean是否需要进行切面增强
		List<Advisor> matchAdvisors = getMatchedAdvisors(bean, beanName); 
		// 如需要就进行增强,再返回增强的对象。
		if (CollectionUtils.isNotEmpty(matchAdvisors)) {
			bean = this.createProxy(bean, beanName, matchAdvisors);
		}
		return bean;
	}
获取所有的方法
	private List<Advisor> getMatchedAdvisors(Object bean, String beanName) {
		if (CollectionUtils.isEmpty(advisors)) {
			return null;
		}

		// 得到类、所有的方法
		Class<?> beanClass = bean.getClass();
		List<Method> allMethods = this.getAllMethodForClass(beanClass);

		// 存放匹配的Advisor的list
		List<Advisor> matchAdvisors = new ArrayList<>();
		// 遍历Advisor来找匹配的
		for (Advisor ad : this.advisors) {
			if (ad instanceof PointcutAdvisor) {
				if (isPointcutMatchBean((PointcutAdvisor) ad, beanClass, allMethods)) {
					matchAdvisors.add(ad);
				}
			}
		}

		return matchAdvisors;
	}

	private List<Method> getAllMethodForClass(Class<?> beanClass) {
		List<Method> allMethods = new LinkedList<>();
		Set<Class<?>> classes = new LinkedHashSet<>(ClassUtils.getAllInterfacesForClassAsSet(beanClass));
		classes.add(beanClass);
		for (Class<?> clazz : classes) {
			Method[] methods = ReflectionUtils.getAllDeclaredMethods(clazz);
			for (Method m : methods) {
				allMethods.add(m);
			}
		}

		return allMethods;
	}
Pointcut进行匹配过程
	private boolean isPointcutMatchBean(PointcutAdvisor pa, Class<?> beanClass, List<Method> methods) {
		Pointcut p = pa.getPointcut();

		// 首先判断类是否匹配
		if (!p.matchsClass(beanClass)) {
			return false;
		}

		// 再判断是否有方法匹配
		for (Method method : methods) {
			if (p.matchsMethod(method, beanClass)) {
				return true;
			}
		}
		return false;
	}
代理增强的逻辑

image

创建代理
	private Object createProxy(Object bean, String beanName, List<Advisor> matchAdvisors) throws Throwable {
		// 通过AopProxyFactory工厂去完成选择、和创建代理对象的工作。
		return AopProxyFactory.getDefaultAopProxyFactory().createAopProxy(bean, beanName, matchAdvisors, beanFactory)
				.getProxy();
	}
public interface AopProxy {
	/**
	 * Create a new proxy object.
	 * <p>
	 * Uses the AopProxy's default class loader (if necessary for proxy
	 * creation): usually, the thread context class loader.
	 * 
	 * @return the new proxy object (never {@code null})
	 * @see Thread#getContextClassLoader()
	 */
	Object getProxy();

	/**
	 * Create a new proxy object.
	 * <p>
	 * Uses the given class loader (if necessary for proxy creation).
	 * {@code null} will simply be passed down and thus lead to the low-level
	 * proxy facility's default, which is usually different from the default
	 * chosen by the AopProxy implementation's {@link #getProxy()} method.
	 * 
	 * @param classLoader
	 *            the class loader to create the proxy with (or {@code null} for
	 *            the low-level proxy facility's default)
	 * @return the new proxy object (never {@code null})
	 */
	Object getProxy(ClassLoader classLoader);

}
public interface AopProxyFactory {

	AopProxy createAopProxy(Object bean, String beanName, List<Advisor> matchAdvisors, BeanFactory beanFactory)
			throws Throwable;

	/**
	 * 获得默认的AopProxyFactory实例
	 * 
	 * @return AopProxyFactory
	 */
	static AopProxyFactory getDefaultAopProxyFactory() {
		return new DefaultAopProxyFactory();
	}
}

Creator怎么使用AopProxy

image

public class DefaultAopProxyFactory implements AopProxyFactory {

	@Override
	public AopProxy createAopProxy(Object bean, String beanName, List<Advisor> matchAdvisors, BeanFactory beanFactory)
			throws Throwable {
		// 是该用jdk动态代理还是cglib?
		if (shouldUseJDKDynamicProxy(bean, beanName)) {
			return new JdkDynamicAopProxy(beanName, bean, matchAdvisors, beanFactory);
		} else {
			return new CglibDynamicAopProxy(beanName, bean, matchAdvisors, beanFactory);
		}
	}

	private boolean shouldUseJDKDynamicProxy(Object bean, String beanName) {
		// 如何判断?
		// 这样可以吗:有实现接口就用JDK,没有就用cglib?
		// 请同学们在读spring的源码时看spring中如何来判断的
		return false;
	}

}
        //CGlib代理
        @Override
	public Object getProxy(ClassLoader classLoader) {
		if (logger.isDebugEnabled()) {
			logger.debug("为" + target + "创建cglib代理。");
		}
		Class<?> superClass = this.target.getClass();
		enhancer.setSuperclass(superClass);
		enhancer.setInterfaces(this.getClass().getInterfaces());
		enhancer.setCallback(this);
		Constructor<?> constructor = null;
		try {
			constructor = superClass.getConstructor(new Class<?>[] {});
		} catch (NoSuchMethodException | SecurityException e) {

		}
		if (constructor != null) {
			return enhancer.create();
		} else {
			BeanDefinition bd = ((DefaultBeanFactory) beanFactory).getBeanDefinition(beanName);
/*
其中这里的bd.getConstructorArgumentRealValues()
	private ThreadLocal<Object[]> realConstructorArgumentValues = new ThreadLocal<>();

	@Override
	public Object[] getConstructorArgumentRealValues() {
		return realConstructorArgumentValues.get();
	}
*/
			return enhancer.create(bd.getConstructor().getParameterTypes(), bd.getConstructorArgumentRealValues());

		}
	}
        //JDK代理
        @Override
	public Object getProxy(ClassLoader classLoader) {
		if (logger.isDebugEnabled()) {
			logger.debug("为" + target + "创建代理。");
		}
		return Proxy.newProxyInstance(classLoader, target.getClass().getInterfaces(), this);
	}
实现增强的逻辑

image

Cglib的使用
	@Override
	public Object intercept(Object proxy, Method method, Object[] args, MethodProxy methodProxy) throws Throwable {
		return AopProxyUtils.applyAdvices(target, method, args, matchAdvisors, proxy, beanFactory);
	}	
        
JDK的代理使用
        @Override
	public Object invoke(Object proxy, Method method, Object[] args) throws Throwable {
		return AopProxyUtils.applyAdvices(target, method, args, matchAdvisors, proxy, beanFactory);
	}

	/**
	 * 对方法应用advices增强
	 */
	public static Object applyAdvices(Object target, Method method, Object[] args, List<Advisor> matchAdvisors,
			Object proxy, BeanFactory beanFactory) throws Throwable {
		// 这里要做什么?
		// 1、获取要对当前方法进行增强的advice
		List<Object> advices = AopProxyUtils.getShouldApplyAdvices(target.getClass(), method, matchAdvisors,
				beanFactory);
		// 2、如有增强的advice,责任链式增强执行
		if (CollectionUtils.isEmpty(advices)) {
			return method.invoke(target, args);
		} else {
			// 责任链式执行增强
			AopAdviceChainInvocation chain = new AopAdviceChainInvocation(proxy, target, method, args, advices);
			return chain.invoke();
		}
	}
	/**
	 * 获取与方法匹配的切面的advices
	 */
	public static List<Object> getShouldApplyAdvices(Class<?> beanClass, Method method, List<Advisor> matchAdvisors,
			BeanFactory beanFactory) throws Throwable {
		if (CollectionUtils.isEmpty(matchAdvisors)) {
			return null;
		}
		List<Object> advices = new ArrayList<>();
		for (Advisor ad : matchAdvisors) {
			if (ad instanceof PointcutAdvisor) {
				if (((PointcutAdvisor) ad).getPointcut().matchsMethod(method, beanClass)) {
					advices.add(beanFactory.getBean(ad.getAdviceBeanName()));
				}
			}
		}

		return advices;
	}

	// 责任链执行记录索引号
	private int i = 0;

	public Object invoke() throws Throwable {
		if (i < this.advices.size()) {
			Object advice = this.advices.get(i++);
			if (advice instanceof MethodBeforeAdvice) {
				// 执行前置增强
				((MethodBeforeAdvice) advice).before(method, args, target);
			} else if (advice instanceof MethodInterceptor) {
				// 执行环绕增强和异常处理增强。注意这里给入的method 和 对象 是invoke方法和链对象
				return ((MethodInterceptor) advice).invoke(invokeMethod, null, this);
			} else if (advice instanceof AfterReturningAdvice) {
				// 当是后置增强时,先得得到结果,再执行后置增强逻辑
				Object returnValue = this.invoke();
				((AfterReturningAdvice) advice).afterReturning(returnValue, method, args, target);
				return returnValue;
			}
			return this.invoke();
		} else {
			return method.invoke(target, args);
		}
	}

对增强的Bean需要判断,是不是需要代理的Bean还是增强的Bean

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值