Spring进阶之路(10)-Advice简介以及通过cglib生成AOP代理对象
2016-03-15 10:58
591 查看
Advice简介
1. Before:在目标方法执行之前执行织入,如果Before的处理中没有进行特殊的处理,那么目标方法最终会执行,但是如果想要阻止目标方法执行时,可以通过抛出一个异常来实现,Before处理无法拿到目标方法的返回值,因为这时候目标方法并未运行。2. AfterReturning: 返回之后执行(前提是目标方法执行成功),可以访问到目标对象的返回值,但是不可以改变返回值。
3. AfterThrowing:抛出异常之后执行,可以对异常进行适当的修复或者将异常输出到日志中。
4. After:不管目标对象执行成功与否都会被织入常用于释放资源等。
5. Around:既可以在目标方法之前,又可以在目标方法调用之后执行,但是需要在线程安全的情况下执行,如果需要目标方法执行之前或者之后共享某种数据,应该考虑用Around。需要改变返回值的时候,只能使用Around。
通过cglib生成AOP代理对象
上一篇文章中已经提到,通过JDK的代理生成AOP代理对象的方式,但是前提是目标方法实现了接口,如果没有实现接口的话,那么怎么办?在这种情况下,我们使用cglib来实现生成AOP代理对象。
定义一个没有实现接口的User类。
package com.siti.spring20160315; public class User { private String userName; private String password; public User(){} public User(String userName, String password) { super(); this.userName = userName; this.password = password; } public String getUserName() { return userName; } public void setUserName(String userName) { this.userName = userName; } public String getPassword() { return password; } public void setPassword(String password) { this.password = password; } public void saySth() { System.out.println("hello!"); } }
对于Spring而言,如果说目标类实现了接口的话,会按照JDK代理生成AOP代理对象,如果没有实现接口的话,那么会使用cglib来生成AOP代理对象。
package com.siti.spring20160315; import java.lang.reflect.Method; import org.springframework.cglib.proxy.Enhancer; import org.springframework.cglib.proxy.InvocationHandler; public class MyProxy4AOPObject implements InvocationHandler{ private Object targetObj; public Object getProxyObject(Object targetObj){ this.targetObj = targetObj; Enhancer enhance = new Enhancer(); // 将目标类设置为代理对象的父类,产生目标类的子类,这个子类覆盖所有父类的非final修饰的方法 enhance.setSuperclass(this.targetObj.getClass()); // 设置回调,可以单独建立一个类实现InvocationHandler接口实现里面的invoke方法 enhance.setCallback(this); return enhance.create(); } @Override public Object invoke(Object proxy, Method method, Object[] args) throws Throwable { User user = (User)this.targetObj; Object result = null; try{ // 拦截,符合要求的才允许运行 if(user.getUserName() != null && user.getUserName() != ""){ // -->Before result = method.invoke(this.targetObj, args); // -->AfterReturning } }catch (Exception e) { // -->AfterThrowing }finally{ // -->After } return result; } }
package com.siti.spring20160315; public class MainTest { public static void main(String[] args) { User user = new User("wy", "wy"); MyProxy4AOPObject myProxy4AOPObject = new MyProxy4AOPObject(); User us = (User) myProxy4AOPObject.getProxyObject(user); us.saySth(); } }这里会输出:hello!
如果将User中name属性赋值为null或者""的话就不会输出,因为在invoke方法中进行了限制,调用的目标对象的方法不会执行。
相关文章推荐
- 用java.util.Observable实现Observer模式
- 加载依赖的jar包在命令行编译和运行java文件
- Java中的访问权限
- Java中HashTable和HashMap的区别
- struts Convention 插件
- Java 基础——String
- java并发库之Executors常用的创建ExecutorService的几个方法说明
- Java获取文件大小的正确方法(转)
- 源码编译的JDK设置
- JavaMail--发送htm邮件
- AXIS(Java WebSerivce)全攻略
- Java Servlet DAO实践(二)
- java整理之集合框架
- 【Java】JAVA中的throws和throw的区别
- java内容介绍
- Java源码阅读之FutureTask
- java并发DCL问题
- Java 入门 之 控制台输出乱码
- JAVA学习第二集:数据类型、运算符
- java动态代理实现