AOP
- JDK的实现
- Clib的实现
源码设计
AdvisedSupport …
@Data
public class AdvisedSupport {
private TargetSource targetSource;
private MethodInterceptor methodInterceptor;
private MethodMatcher methodMatcher;
}
TargetSource …
@Data
@NoArgsConstructor
@AllArgsConstructor
@Builder
public class TargetSource {
//目标代理的实现类
private Class<?> targetClass;
//目标代理类的接口
private Class<?>[] interfaces;
//目标对象
private Object target;
public TargetSource(Object target, Class<?> targetClass,Class<?>... interfaces) {
this.target = target;
this.targetClass = targetClass;
this.interfaces = interfaces;
}
}
拦截器
public class TimerInterceptor implements MethodInterceptor {
@Override
public Object invoke(MethodInvocation invocation) throws Throwable {
long time = System.nanoTime();
System.out.println("Invocation of Method " + invocation.getMethod().getName() + " start!");
Object proceed = invocation.proceed();
System.out.println("Invocation of Method " + invocation.getMethod().getName() + " end! takes " + (System.nanoTime() - time)
+ " nanoseconds.");
return proceed;
}
}
顶层获取代理类对象
public interface AopProxy {
Object getProxy();
}
public abstract class AbstractAopProxy implements AopProxy {
protected AdvisedSupport advised;
public AbstractAopProxy(AdvisedSupport advised) {
this.advised = advised;
}
}
public class JdkDynamicAopProxy extends AbstractAopProxy implements InvocationHandler {
public JdkDynamicAopProxy(AdvisedSupport advised) {
super(advised);
}
@Override
public Object getProxy() {
return Proxy.newProxyInstance(getClass().getClassLoader(), advised.getTargetSource().getInterfaces(), this);
}
@Override
public Object invoke(Object proxy, Method method, Object[] args) throws Throwable {
MethodInterceptor methodInterceptor = advised.getMethodInterceptor();
if (advised.getMethodMatcher() != null &&
//
advised.getMethodMatcher().matches(method, advised.getTargetSource().getClass())) {
return methodInterceptor.invoke(new ReflectiveMethodInvocation(advised.getTargetSource().getTarget(),
method, args));
} else {
// 反射调用执行目标实现类的方法
// return methodInterceptor.invoke(new ReflectiveMethodInvocation(advised.getTargetSource().getTarget(),
// method, args));
return method.invoke(advised.getTargetSource().getTarget(), args);
}
}
}
public class JdkDynamicAopProxyTest {
@Test
public void testInterceptor() throws Exception {
// --------- helloWorldService without AOP
ApplicationContext applicationContext = new ClassPathXmlApplicationContext("tinyioc.xml");
CatDemo cat = (CatDemo)applicationContext.getBean("cat");;
System.out.println(cat.getCat());
// 1. 设置被代理对象(Joinpoint)
AdvisedSupport advisedSupport = new AdvisedSupport();
TargetSource targetSource = new TargetSource(cat, CatDemoImpl.class,
CatDemo.class);
advisedSupport.setTargetSource(targetSource);
// 2. 设置拦截器(Advice)
TimerInterceptor timerInterceptor = new TimerInterceptor();
advisedSupport.setMethodInterceptor(timerInterceptor);
// 3. 创建代理(Proxy)
JdkDynamicAopProxy jdkDynamicAopProxy = new JdkDynamicAopProxy(advisedSupport);
CatDemo helloWorldServiceProxy = (CatDemo) jdkDynamicAopProxy.getProxy();
// 4. 基于AOP的调用
helloWorldServiceProxy.getCat();
}
如何与spring定义的IOC接口实现自动配置
<bean id="autoProxyCreator" class="com.cn.spring.aop.AspectJAwareAdvisorAutoProxyCreator"></bean>
<bean id="child" class="com.cn.spring.bean.ChildDemo"></bean>
<bean id = "cat" class="com.cn.spring.bean.CatDemoImpl"></bean>
<bean id="timerInterceptor" class="com.cn.spring.aop.TimerInterceptor"></bean>
<bean id="aspectjAspect" class="com.cn.spring.aop.AspectJExpressionPointcutAdvisor">
<property name="advice" ref="timerInterceptor"></property>
<property name="expression" value="execution(* com.cn.spring.bean.*.*(..))"></property>
</bean>
获取bean工厂
public interface BeanFactoryAware {
void setBeanFactory(BeanFactory beanFactory) throws Exception;
}
实现自动装配类
public interface BeanPostProcessor {
Object postProcessBeforeInitialization(Object bean, String beanName) throws Exception;
Object postProcessAfterInitialization(Object bean, String beanName) throws Exception;
}
public class AspectJAwareAdvisorAutoProxyCreator implements BeanPostProcessor, BeanFactoryAware {
private AbstractBeanFactory beanFactory;
@Override
public void setBeanFactory(BeanFactory beanFactory) throws Exception {
this.beanFactory = (AbstractBeanFactory) beanFactory;
}
@Override
public Object postProcessBeforeInitialization(Object bean, String beanName) throws Exception {
return bean;
}
@Override
public Object postProcessAfterInitialization(Object bean, String beanName) throws Exception {
if (bean instanceof AspectJExpressionPointcutAdvisor) {
return bean;
}
if (bean instanceof MethodInterceptor) {
return bean;
}
List<AspectJExpressionPointcutAdvisor> advisors = beanFactory
.getBeansForType(AspectJExpressionPointcutAdvisor.class);
for (AspectJExpressionPointcutAdvisor advisor : advisors) {
if (advisor.getPointcut().getClassFilter().matches(bean.getClass())) {
ProxyFactory advisedSupport = new ProxyFactory();
advisedSupport.setMethodInterceptor((MethodInterceptor) advisor.getAdvice());
advisedSupport.setMethodMatcher(advisor.getPointcut().getMethodMatch());
TargetSource targetSource = new TargetSource(bean, bean.getClass(), bean.getClass().getInterfaces());
advisedSupport.setTargetSource(targetSource);
return advisedSupport.getProxy();
}
}
return bean;
}
}
public interface Advisor {
Advice getAdvice();
}
public interface PointcutAdvisor extends Advisor{
Pointcut getPointcut();
}
public class AspectJExpressionPointcutAdvisor implements PointcutAdvisor {
private AspectJExpressionPointcut pointcut = new AspectJExpressionPointcut();
private Advice advice;
public void setAdvice(Advice advice) {
this.advice = advice;
}
public void setExpression(String expression) {
this.pointcut.setExpression(expression);
}
@Override
public Pointcut getPointcut() {
return pointcut;
}
@Override
public Advice getAdvice() {
return advice;
}
}
这里为什么这么封装、是因为每个类对外方法使用。
public interface Pointcut {
ClassFilter getClassFilter();
MethodMatcher getMethodMatch();
}
public interface ClassFilter {
boolean matches(Class targetClass);
}
public interface MethodMatcher {
boolean matches(Method method, Class targetClass);
}
public class AspectJExpressionPointcut implements Pointcut, ClassFilter, MethodMatcher {
private PointcutParser pointcutParser;
private String expression;
private PointcutExpression pointcutExpression;
private static final Set<PointcutPrimitive> DEFAULT_SUPPORTED_PRIMITIVES = new HashSet<PointcutPrimitive>();
static {
DEFAULT_SUPPORTED_PRIMITIVES.add(PointcutPrimitive.EXECUTION);
DEFAULT_SUPPORTED_PRIMITIVES.add(PointcutPrimitive.ARGS);
DEFAULT_SUPPORTED_PRIMITIVES.add(PointcutPrimitive.REFERENCE);
DEFAULT_SUPPORTED_PRIMITIVES.add(PointcutPrimitive.THIS);
DEFAULT_SUPPORTED_PRIMITIVES.add(PointcutPrimitive.TARGET);
DEFAULT_SUPPORTED_PRIMITIVES.add(PointcutPrimitive.WITHIN);
DEFAULT_SUPPORTED_PRIMITIVES.add(PointcutPrimitive.AT_ANNOTATION);
DEFAULT_SUPPORTED_PRIMITIVES.add(PointcutPrimitive.AT_WITHIN);
DEFAULT_SUPPORTED_PRIMITIVES.add(PointcutPrimitive.AT_ARGS);
DEFAULT_SUPPORTED_PRIMITIVES.add(PointcutPrimitive.AT_TARGET);
}
public AspectJExpressionPointcut() {
this(DEFAULT_SUPPORTED_PRIMITIVES);
}
public AspectJExpressionPointcut(Set<PointcutPrimitive> supportedPrimitives) {
pointcutParser = PointcutParser
.getPointcutParserSupportingSpecifiedPrimitivesAndUsingContextClassloaderForResolution(supportedPrimitives);
}
protected void checkReadyToMatch() {
if (pointcutExpression == null) {
pointcutExpression = buildPointcutExpression();
}
}
private PointcutExpression buildPointcutExpression() {
return pointcutParser.parsePointcutExpression(expression);
}
public void setExpression(String expression) {
this.expression = expression;
}
@Override
public boolean matches(Class targetClass) {
checkReadyToMatch();
return pointcutExpression.couldMatchJoinPointsInType(targetClass);
}
@Override
public boolean matches(Method method, Class targetClass) {
// 检查表达式是否正常
checkReadyToMatch();
ShadowMatch shadowMatch = pointcutExpression.matchesMethodExecution(method);
if (shadowMatch.alwaysMatches()) {
return true;
} else if (shadowMatch.neverMatches()) {
return false;
}
return false;
}
@Override
public ClassFilter getClassFilter() {
return this;
}
@Override
public MethodMatcher getMethodMatch() {
return this;
}
}
public class ProxyFactory extends AdvisedSupport implements AopProxy {
@Override
public Object getProxy() {
return createAopProxy().getProxy();
}
protected final AopProxy createAopProxy() {
return new Cglib2AopProxy(this);
}
}
public class Cglib2AopProxy extends AbstractAopProxy {
public Cglib2AopProxy(AdvisedSupport advised) {
super(advised);
}
@Override
public Object getProxy() {
Enhancer enhancer = new Enhancer();
enhancer.setSuperclass(advised.getTargetSource().getTargetClass());
enhancer.setInterfaces(advised.getTargetSource().getInterfaces());
enhancer.setCallback(new DynamicAdvisedInterceptor(advised));
Object enhanced = enhancer.create();
return enhanced;
}
private static class DynamicAdvisedInterceptor implements MethodInterceptor {
private AdvisedSupport advised;
private org.aopalliance.intercept.MethodInterceptor delegateMethodInterceptor;
private DynamicAdvisedInterceptor(AdvisedSupport advised) {
this.advised = advised;
this.delegateMethodInterceptor = advised.getMethodInterceptor();
}
@Override
public Object intercept(Object obj, Method method, Object[] args, MethodProxy proxy) throws Throwable {
if (advised.getMethodMatcher() == null
|| advised.getMethodMatcher().matches(method, advised.getTargetSource().getTargetClass())) {
return delegateMethodInterceptor.invoke(new CglibMethodInvocation(advised.getTargetSource().getTarget(), method, args, proxy));
}
return new CglibMethodInvocation(advised.getTargetSource().getTarget(), method, args, proxy).proceed();
}
}
private static class CglibMethodInvocation extends ReflectiveMethodInvocation {
private final MethodProxy methodProxy;
public CglibMethodInvocation(Object target, Method method, Object[] args, MethodProxy methodProxy) {
super(target, method, args);
this.methodProxy = methodProxy;
}
@Override
public Object proceed() throws Throwable {
return this.methodProxy.invoke(this.target, this.arguments);
}
}
}