对方进行预处理和后处理的两种方法:动态代理和Spring AOP中的Advice,具体的是使用举例如下:
1) 首先是公用部分的声明:定义了一个接口和对应的实现类,以及用来判断拦截方法的两个注解。
首先定义一个接口
void sayMySelf(String self);
}
接口的实现
public class HelloImpl implements Hello {
@Override
//@MethodLog("执行 问候")
public void sayHello(String name) {
System.out.println("hello, " + name);
}
@Override
public void sayMySelf(String self) {
System.out.println("hello "+self);
}
public static void main(String[] args) {
Hello hello = new HelloImpl();
hello.sayHello("alice");
}
}
定义两个注解
注解1的定义
@Target({ METHOD })
@Retention(RUNTIME)
public @interface MethodLog {
public String value() default "";
}
注解2的定义
@Target({ METHOD })
@Retention(RUNTIME)
public @interface MyMethodLog {
public String value() default "";
}
2)使用代理的方式拦截
目的:通过动态代理的方式拦截要代理类的所有方法,然后判断拦截到的方法上是否标注了MethodLog的注解,
如果是,在执行方法的前后分别输出:方法名 Beging.和方法名 End.
定义一个实现了InvocationHandler接口的类,实现invoke方法
public class ProxyInvocationHandler implements InvocationHandler {
private Object target;
public ProxyInvocationHandler(Object target) {
this.target = target;
}
@Override
public Object invoke(Object proxy, Method method, Object[] args) throws Throwable {
//判断拦截到的方法是否有MethodLog的注解
boolean methodLogAnnotated = method.isAnnotationPresent(MethodLog.class);
if (methodLogAnnotated) {
System.out.println(method.getName() + " Begin.");
}
//通过反射的方式调用被代理的对象的方法
Object ret = method.invoke(target, args);
if (methodLogAnnotated) {
System.out.println(method.getName() + " End.");
}
return ret;
}
}
上述定义的代理类的使用的方式
public class ProxyCall {
public static void main(String[] args) {
final Hello hello = new HelloImpl();
Hello helloProxy = (Hello) Proxy.newProxyInstance(Hello.class.getClassLoader(), new Class<?>[] { Hello.class },
new ProxyInvocationHandler(hello));
helloProxy.sayHello("alice");
}
}
3)使用Spring AOP中的Advice拦截
目的:通过Advice的方式,在被拦截到的所有方法执行前后输出一些信息,如果被拦截的方法上标注了MethoLog注解,
在该方法执行的前后分别输出:执行 问候 Begin.和执行 问候 end.;如果被拦截的方法上标注了MyMethod注解,在该方法
执行的前后分别输出:执行 slef Begin.和执行 self End.
首先定义实现了 MethodBeforeAdvice和 AfterReturningAdvice接口的类,分别实现他们各自的before方法和after方法
public class MethodLogAdvice implements MethodBeforeAdvice, AfterReturningAdvice {
@Override
public void before(Method method, Object[] args, Object target) throws Throwable {
//获取方法的所有注解
Annotation[] annotations = method.getAnnotations();
for (Annotation annotation : annotations) {
if (annotation.annotationType() == MethodLog.class) {
//标注了MethodLog注解的处理
MethodLog methodLog = method.getAnnotation(MethodLog.class);
System.out.println(methodLog.value()+" Begin.");
}else if(annotation.annotationType() == MyMethodLog.class){
//标注了MyMethodLog 注解的处理
MyMethodLog myMethodLog = method.getAnnotation(MyMethodLog.class);
System.out.println(myMethodLog.value() + " Begin");
}
}
}
@Override
public void afterReturning(Object returnValue, Method method, Object[] args, Object target) throws Throwable {
Annotation[] annotations = method.getAnnotations();
for (Annotation annotation : annotations) {
if (annotation.annotationType() == MethodLog.class) {
MethodLog methodLog = method.getAnnotation(MethodLog.class);
System.out.println(methodLog.value()+" Begin.");
}else if(annotation.annotationType() == MyMethodLog.class){
MyMethodLog myMethodLog = method.getAnnotation(MyMethodLog.class);
System.out.println(myMethodLog.value() + " Begin");
}
}
}
}
使用的方式:
public class SpringAOP {
public static void main(String[] args) {
//定义代理工厂
ProxyFactory factory = new ProxyFactory(new HelloImpl());
//为代理工厂添加接口
factory.addInterface(Hello.class);
MethodLogAdvice advice = new MethodLogAdvice();
// 为代理工厂添加自己定义的Advice
factory.addAdvice(advice);
Hello hello = (Hello) factory.getProxy();
hello.sayHello("alice");
hello.sayMySelf("self");
}
}
1) 首先是公用部分的声明:定义了一个接口和对应的实现类,以及用来判断拦截方法的两个注解。
首先定义一个接口
public interface Hello {
@MethodLog("执行 问候")void sayHello(String name);
void sayMySelf(String self);
}
接口的实现
public class HelloImpl implements Hello {
@Override
//@MethodLog("执行 问候")
public void sayHello(String name) {
System.out.println("hello, " + name);
}
@Override
public void sayMySelf(String self) {
System.out.println("hello "+self);
}
public static void main(String[] args) {
Hello hello = new HelloImpl();
hello.sayHello("alice");
}
}
定义两个注解
注解1的定义
@Target({ METHOD })
@Retention(RUNTIME)
public @interface MethodLog {
public String value() default "";
}
注解2的定义
@Target({ METHOD })
@Retention(RUNTIME)
public @interface MyMethodLog {
public String value() default "";
}
2)使用代理的方式拦截
目的:通过动态代理的方式拦截要代理类的所有方法,然后判断拦截到的方法上是否标注了MethodLog的注解,
如果是,在执行方法的前后分别输出:方法名 Beging.和方法名 End.
定义一个实现了InvocationHandler接口的类,实现invoke方法
public class ProxyInvocationHandler implements InvocationHandler {
private Object target;
public ProxyInvocationHandler(Object target) {
this.target = target;
}
@Override
public Object invoke(Object proxy, Method method, Object[] args) throws Throwable {
//判断拦截到的方法是否有MethodLog的注解
boolean methodLogAnnotated = method.isAnnotationPresent(MethodLog.class);
if (methodLogAnnotated) {
System.out.println(method.getName() + " Begin.");
}
//通过反射的方式调用被代理的对象的方法
Object ret = method.invoke(target, args);
if (methodLogAnnotated) {
System.out.println(method.getName() + " End.");
}
return ret;
}
}
上述定义的代理类的使用的方式
public class ProxyCall {
public static void main(String[] args) {
final Hello hello = new HelloImpl();
Hello helloProxy = (Hello) Proxy.newProxyInstance(Hello.class.getClassLoader(), new Class<?>[] { Hello.class },
new ProxyInvocationHandler(hello));
helloProxy.sayHello("alice");
}
}
3)使用Spring AOP中的Advice拦截
目的:通过Advice的方式,在被拦截到的所有方法执行前后输出一些信息,如果被拦截的方法上标注了MethoLog注解,
在该方法执行的前后分别输出:执行 问候 Begin.和执行 问候 end.;如果被拦截的方法上标注了MyMethod注解,在该方法
执行的前后分别输出:执行 slef Begin.和执行 self End.
首先定义实现了 MethodBeforeAdvice和 AfterReturningAdvice接口的类,分别实现他们各自的before方法和after方法
public class MethodLogAdvice implements MethodBeforeAdvice, AfterReturningAdvice {
@Override
public void before(Method method, Object[] args, Object target) throws Throwable {
//获取方法的所有注解
Annotation[] annotations = method.getAnnotations();
for (Annotation annotation : annotations) {
if (annotation.annotationType() == MethodLog.class) {
//标注了MethodLog注解的处理
MethodLog methodLog = method.getAnnotation(MethodLog.class);
System.out.println(methodLog.value()+" Begin.");
}else if(annotation.annotationType() == MyMethodLog.class){
//标注了MyMethodLog 注解的处理
MyMethodLog myMethodLog = method.getAnnotation(MyMethodLog.class);
System.out.println(myMethodLog.value() + " Begin");
}
}
}
@Override
public void afterReturning(Object returnValue, Method method, Object[] args, Object target) throws Throwable {
Annotation[] annotations = method.getAnnotations();
for (Annotation annotation : annotations) {
if (annotation.annotationType() == MethodLog.class) {
MethodLog methodLog = method.getAnnotation(MethodLog.class);
System.out.println(methodLog.value()+" Begin.");
}else if(annotation.annotationType() == MyMethodLog.class){
MyMethodLog myMethodLog = method.getAnnotation(MyMethodLog.class);
System.out.println(myMethodLog.value() + " Begin");
}
}
}
}
使用的方式:
public class SpringAOP {
public static void main(String[] args) {
//定义代理工厂
ProxyFactory factory = new ProxyFactory(new HelloImpl());
//为代理工厂添加接口
factory.addInterface(Hello.class);
MethodLogAdvice advice = new MethodLogAdvice();
// 为代理工厂添加自己定义的Advice
factory.addAdvice(advice);
Hello hello = (Hello) factory.getProxy();
hello.sayHello("alice");
hello.sayMySelf("self");
}
}