1 spring核心AOP
spring aop 實(shí)現(xiàn)方式,網(wǎng)上看到大神的示例,非常的清晰,鏈接如下,總共4篇:
http://tonl.iteye.com/blog/1965740
spring AOP 獲得代理方式有兩種 JDK動(dòng)態(tài)代理督怜,CGLib生成代理
1. 關(guān)于JDK動(dòng)態(tài)代理核心
JDK動(dòng)態(tài)代理核心就是InvocationHandler接口
動(dòng)態(tài)代理一般使用Proxy類來實(shí)現(xiàn),代理類要實(shí)現(xiàn)InvocationHandler接口檐嚣,并復(fù)寫他的invoke方法拯勉,再由Proxy.newProxyInstance方法來獲得代理類的實(shí)例
package proxyofdynamic;
import java.lang.reflect.InvocationHandler;
import java.lang.reflect.Method;
import java.lang.reflect.Proxy;
/**
* 本例實(shí)現(xiàn)的是動(dòng)態(tài)代理的模式
* @author fun
*
*/
public class RunTest implements InvocationHandler {
Object any_object;
//申明bind方法,返回代理對(duì)象
public Object bind(Object any_object){
this.any_object = any_object;
return Proxy.newProxyInstance(any_object.getClass().getClassLoader(), any_object.getClass().getInterfaces(), this);
}
//自己的業(yè)務(wù)邏輯践叠,被代理方法前的處理
public void methodbefore(){
System.out.println("start to print");
}
public Object invoke(Object arg0, Method arg1, Object[] arg2)
throws Throwable {
Object obj_return = null;
this.methodbefore();
obj_return = arg1.invoke(any_object, arg2);
System.out.println("end of print");
return obj_return;
}
public static void main(String[] args) {
RunTest run = new RunTest();
hello_interface hello = (hello_interface)run.bind(new hello_interface_impl());
hello.sayHello();
}
}
核心就是利用invoke方法回調(diào)巧涧,在回調(diào)前后處理自己切入的業(yè)務(wù)璃赡。上面的簡(jiǎn)單示例測(cè)試了在執(zhí)行接口hello_interface的sayHello方法前調(diào)用自定義的邏輯methedbefore.當(dāng)然也可以獲得方法參數(shù)判哥。從invoke的方法參數(shù)中獲得。
2 spring基于aspectJ完成aop
使用aspectj的方式完成aop的時(shí)候更加方便快捷碉考,使用中有兩種方式塌计,xml配置或者annotation 方式。簡(jiǎn)單給個(gè)annotation的示例豆励。
package com.fun.spring;
import org.aspectj.lang.JoinPoint;
import org.aspectj.lang.ProceedingJoinPoint;
import org.aspectj.lang.annotation.*;
import org.springframework.stereotype.Component;
/**
* aspectJ 實(shí)現(xiàn)的AOP
* Created by fun
*
* @date 2017/5/5.
*/
@Aspect
@Component
public class TestAOP {
// 定義pointcut夺荒,然后再@before ,@after @Around 中使用×颊簦或者直接在這些
// 注解中直接定義execution
@Pointcut("execution(* com.fun.spring.TestBean.testMethod())")
public void before() {
}
@Pointcut("execution(* com.fun.spring.TestBean.testMethod())")
public void after() {
}
// @Pointcut("execution(* com.fun.spring.TestBean.testMethod())")
// public void around() {
// }
@Before("before() ")
public void beforeMethod(JoinPoint pjp) throws Throwable {
System.out.println("before method....");
}
@After("after() ")
public void afterMethod(JoinPoint pjp) throws Throwable {
System.out.println("after method....");
}
@Around("execution(* com.fun.spring.TestBean.testMethod())")
public Object aroundMethod(ProceedingJoinPoint pjp) throws Throwable {
Object[] obj = pjp.getArgs();
System.out.println("before proceed");
// around 和 before after的最大區(qū)別在于技扼,around可以控制方法是否執(zhí)行
Object result = pjp.proceed(obj);
System.out.println("after proceed");
return null;
}
}
隨便一個(gè)bean,使用@Aspect 注解即可。但是要在spring的配置加上<aop:aspectj-autoproxy/>
才行嫩痰。
上面示例中有一點(diǎn)值得注意的地方就是剿吻,@Around里面主動(dòng)調(diào)用了pjp.proceed(obj).所以他可以控制切面里面的方法是否執(zhí)行。例如在執(zhí)行前校驗(yàn)串纺,如果不滿足條件丽旅,不執(zhí)行次方法椰棘。而@before 和 @after 沒有這種特性。