首页   快速返回

AOP要点整理     所属分类 spring
AOP 面向切面编程 Aspect Oriented Programming
主要应用场景 日志记录 权限校验 异常处理 事务控制

术语 
target 目标类 
proxy 代理 
joinPoint 连接点
在spring中只支持方法连接点,连接点指的是可以使用advice(增强)的地方,例如一个类中有5个方法,那么这5个方法都可以是连接点。

pointcut 切点 
切入advice(增强)的连接点。

advice 增强 想要添加的功能,如日志、权限校验
advisor 切面  切点+增强 
weaving 织入  即对方法的增强,将切面的代码织入(应用)到目标函数的过程。
introduction 引入 对类的增强 增加方法


AOP实现方案

硬编码
静态代理 
动态代理 jdk动态代理 基于接口  cglib动态代理 
spring aop  编程式  声明式 (手工 自动扫描)

spring aspectj  基于注解   基于xml配置 

java.lang.reflect.Method
java.lang.reflect.Proxy
java.lang.reflect.InvocationHandler
public Object invoke(Object proxy, Method method, Object[] args)

Proxy
public static Object newProxyInstance(ClassLoader loader, Class[] interfaces,InvocationHandler h)



org.springframework.cglib.proxy.Enhancer
org.springframework.cglib.proxy.MethodInterceptor
org.springframework.cglib.proxy.MethodProxy


 public Object intercept(Object target, Method method, Object[] args, MethodProxy proxy)

public class ProxyFactory implements MethodInterceptor {  
     //要代理的原始对象  
    private Object obj;  
    public Object createProxy(Object target) {  
        this.obj = target;  
        Enhancer enhancer = new Enhancer();  
        enhancer.setSuperclass(this.obj.getClass());// 设置代理目标  
        enhancer.setCallback(this);// 设置回调  
        enhancer.setClassLoader(target.getClass().getClassLoader());  
        return enhancer.create();  
    }  


 Hello hello = new Hello();  
        ProxyFactory cglibProxy = new ProxyFactory();  
        Hello proxy = (Hello) cglibProxy.createProxy(hello);  
        String result=proxy.sayHello();  
        System.out.println(result); 



// 编程式前置增强
public class UserBeforeAdvice implements MethodBeforeAdvice {
    @Override
    public void before(Method method, Object[] args, Object target) throws Throwable {
        System.out.println("Before");
    }
}


// 编程式后置增强
public class UserAfterAdvice implements  AfterReturningAdvice  {
 
    @Override
    public void afterReturning(Object returnValue, Method method, Object[] args, Object target) throws Throwable {
        System.out.println("After");
    }
}


// 编程式环绕增强
public class UserAroundAdvice implements MethodInterceptor{
    @Override
    public Object invoke(MethodInvocation invocation) throws Throwable {
        System.out.println("Before");
        Object result = invocation.proceed();
        System.out.println("After");
        return result;
    }
}


ProxyFactory proxyFactory = new ProxyFactory();//创建代理工厂
proxyFactory.setTarget(new UserServiceImpl());//射入目标类对象
proxyFactory.addAdvice(new UserBeforeAdvice());//添加前置增强
proxyFactory.addAdvice(new UserAfterAdvice());//添加后置增强
UserService userService = (UserService) proxyFactory.getProxy();//从代理工厂获取代理
userService.queryAll();//调用代理的方法



<context:component-scan base-package="com.xxx" / >

 <bean id="userServiceProxy" class="org.springframework.aop.framework.ProxyFactoryBean">
        <property name="interfaces" value="com.xxx.UserService"/>
        <property name="target" ref="userServiceImpl"/>
        <property name="interceptorNames">
            <list>
                <value >userAroundAdvice</value>
            </list >
        </property>
</bean >


 

@Aspect 
@Around("execution(* com.xxx.HelloServiceImpl.*(..))")




<context:component-scan base-package="com.xxx"/>

<aop:aspectj-autoproxy proxy-target-class="true"/>



使用注解 拦截指定方法

@Retention(RetentionPolicy.RUNTIME)
@Target(ElementType.METHOD)
@Documented
public @interface Log {
  
}


@Aspect
@Component
public class LogAspect {
   @Before(value = "@annotation(com.xxx.Log)")
    public void before(JoinPoint joinPoint) {
        // 目标类名称
        String targetClazzName = joinPoint.getTarget().getClass().getName();
        // 目标方法名称
        String targetMethodName = joinPoint.getSignature().getName();
    }
}


public class UserAdvisor {

    public Object arount(ProceedingJoinPoint joinPoint) throws Throwable {
        before();
        Object result = joinPoint.proceed();
        after();
        return result;
    }

    public void before() {
        System.out.println("Before");
    }

    public void after() {
        System.out.println("After");
    }
}



<context:component-scan base-package="com.xxx"/>

    <bean id="userServiceImpl" class="com.xxx.UserServiceImpl"/>
    <bean id="userAdvisor" class="com.xxx.UserAdvisor"/>

    <aop:config>
        <aop:aspect ref="userAdvisor">
            <aop:around method="arount" pointcut="execution(* com.xxx.UserServiceImpl.*(..))"></aop:around>
        </aop:aspect>
    </aop:config>



上一篇     下一篇
带孙谣第二篇

程序员眼中的女人

高性能服务器性能优化

linux命令速查

币圈修炼指南

让程序员抓狂的那些事儿