`

java使用动态代理来实现AOP(日志记录)

 
阅读更多

AOP(面向方面)的思想,就是把项目共同的那部分功能分离开来,比如日志记录,避免在业务逻辑里面夹杂着跟业务逻辑无关的代码。

下面是一个AOP实现的简单例子:

首先定义一些业务方法:

复制代码
 1 /**
 2  * Created with IntelliJ IDEA.
 3  * Author: wangjie  email:tiantian.china.2@gmail.com
 4  * Date: 13-9-23
 5  * Time: 下午3:49
 6  */
 7 public interface BussinessService {
 8     public String login(String username, String password);
 9     public String find();
10 }
11 
12 public class BussinessServiceImpl implements BussinessService {
13     private Logger logger = Logger.getLogger(this.getClass().getSimpleName());
14 
15     @Override
16     public String login(String username, String password) {
17         return "login success";
18     }
19 
20     @Override
21     public String find() {
22         return "find success";
23     }
24 
25 }
复制代码
复制代码
 1 /**
 2  * Created with IntelliJ IDEA.
 3  * Author: wangjie  email:tiantian.china.2@gmail.com
 4  * Date: 13-9-24
 5  * Time: 上午10:27
 6  */
 7 public interface WorkService {
 8     public String work();
 9     public String sleep();
10 }
11 
12 public class WorkServiceImpl implements WorkService{
13     @Override
14     public String work() {
15         return "work success";
16     }
17 
18     @Override
19     public String sleep() {
20         return "sleep success";
21     }
22 }
复制代码

实现InvocationHandler接口,使用map来存储不同的InvocationHandler对象,避免生成过多。

复制代码
 1 /**
 2  * Created with IntelliJ IDEA.
 3  * Author: wangjie  email:tiantian.china.2@gmail.com
 4  * Date: 13-9-23
 5  * Time: 下午3:47
 6  */
 7 public class LogInvoHandler implements InvocationHandler{
 8     private Logger logger = Logger.getLogger(this.getClass().getSimpleName());
 9 
10     private Object target; // 代理目标
11     private Object proxy; // 代理对象
12 
13     private static HashMap<Class<?>, LogInvoHandler> invoHandlers = new HashMap<Class<?>, LogInvoHandler>();
14 
15     private LogInvoHandler() {
16     }
17 
18     /**
19      * 通过Class来生成动态代理对象Proxy
20      * @param clazz
21      * @return
22      */
23     public synchronized static Object getProxyInstance(Class<?> clazz){
24         LogInvoHandler invoHandler = invoHandlers.get(clazz);
25 
26         if(null == invoHandler){
27             invoHandler = new LogInvoHandler();
28             try {
29                 Object tar = clazz.newInstance();
30                 invoHandler.setTarget(tar);
31                 invoHandler.setProxy(Proxy.newProxyInstance(tar.getClass().getClassLoader(),
32                         tar.getClass().getInterfaces(), invoHandler));
33             } catch (Exception e) {
34                 e.printStackTrace();
35             }
36             invoHandlers.put(clazz, invoHandler);
37 
38         }
39 
40         return invoHandler.getProxy();
41     }
42 
43     @Override
44     public Object invoke(Object proxy, Method method, Object[] args) throws Throwable {
45 
46         Object result = method.invoke(target, args); // 执行业务处理
47 
48         // 打印日志
49         logger.info("____invoke method: " + method.getName()
50                     + "; args: " + (null == args ? "null" : Arrays.asList(args).toString())
51                     + "; return: " + result);
52 
53 
54         return result;
55     }
56 
57     public Object getTarget() {
58         return target;
59     }
60 
61     public void setTarget(Object target) {
62         this.target = target;
63     }
64 
65     public Object getProxy() {
66         return proxy;
67     }
68 
69     public void setProxy(Object proxy) {
70         this.proxy = proxy;
71     }
72 }
复制代码

然后编写一个Test类测试:

复制代码
 1 /**
 2  * Created with IntelliJ IDEA.
 3  * Author: wangjie  email:tiantian.china.2@gmail.com
 4  * Date: 13-9-24
 5  * Time: 上午9:54
 6  */
 7 public class Test {
 8     public static Logger logger = Logger.getLogger(Test.class.getSimpleName());
 9     public static void main(String[] args) {
10 
11         BussinessService bs = (BussinessService)LogInvoHandler.getProxyInstance(BussinessServiceImpl.class);
12         bs.login("zhangsan", "123456");
13         bs.find();
14 
15         logger.info("--------------------------------------");
16 
17         WorkService ws = (WorkService)LogInvoHandler.getProxyInstance(WorkServiceImpl.class);
18         ws.work();
19         ws.sleep();
20 
21         logger.info("--------------------------------------");
22 
23         BussinessService bss = (BussinessService)LogInvoHandler.getProxyInstance(BussinessServiceImpl.class);
24         bss.login("lisi", "654321");
25         bss.find();
26 
27     }
28 }
复制代码

以后需要添加新的业务逻辑XXXService,只需要调用

XXXService xs = (XXXService)LogInvoHandler.getProxyInstance(XXXServiceImpl.class);

即可。

也可以模仿Spring等框架的配置,把bean的类名配置在xml文件中,如:

<bean id="bussinessService" class="com.wangjie.aoptest2.service.impl.BussinessServiceImpl">

然后在java代码中解析xml,通过Class.forName("com.wangjie.aoptest2.service.impl.BussinessServiceImpl");获得Class对象

然后通过LogInvoHandler.getProxyInstance(Class.forName("com.wangjie.aoptest2.service.impl.BussinessServiceImpl"));获得代理对象Proxy

再使用反射去调用代理对象的方法。

 

运行结果如下:

九月 24, 2013 11:08:03 上午 com.wangjie.aoptest2.invohandler.LogInvoHandler invoke
INFO: ____invoke method: login; args: [zhangsan, 123456]; return: login success
九月 24, 2013 11:08:03 上午 com.wangjie.aoptest2.invohandler.LogInvoHandler invoke
INFO: ____invoke method: find; args: null; return: find success
九月 24, 2013 11:08:03 上午 com.wangjie.aoptest2.Test main
INFO: --------------------------------------
九月 24, 2013 11:08:03 上午 com.wangjie.aoptest2.invohandler.LogInvoHandler invoke
INFO: ____invoke method: work; args: null; return: work success
九月 24, 2013 11:08:03 上午 com.wangjie.aoptest2.invohandler.LogInvoHandler invoke
INFO: ____invoke method: sleep; args: null; return: sleep success
九月 24, 2013 11:08:03 上午 com.wangjie.aoptest2.Test main
INFO: --------------------------------------
九月 24, 2013 11:08:03 上午 com.wangjie.aoptest2.invohandler.LogInvoHandler invoke
INFO: ____invoke method: login; args: [lisi, 654321]; return: login success
九月 24, 2013 11:08:03 上午 com.wangjie.aoptest2.invohandler.LogInvoHandler invoke
INFO: ____invoke method: find; args: null; return: find success

3
7
分享到:
评论

相关推荐

    java使用动态代理来实现AOP(日志记录)的实例代码共6

    java使用动态代理来实现AOP(日志记录)的实例代码共6页.pdf.zip

    aop思想的java实现

    aop思想的java代码实现。代码分三个部分,一个是不使用aop思想实现日志记录,一个是使用静态代理实现aop,最后是使用java 1.3之后的动态代理机制实现。

    java 实现AOP

     为了简单起见,例子没有没有使用任何第三方的AOP Framework, 而是利用Java语言本身自带的动态代理功能来实现AOP.  让我们先回到AOP本身,AOP主要应用于日志记录,性能统计,安全控制,事务处理等方面。它的主要...

    Java AOP研究

    一、 用Java动态代理实现AOP 假设系统由一系列的BusinessObject所完成业务逻辑功能,系统要求在每一次业务逻辑处理时要做日志记录。

    # 动态代理的应用场.md

    首先,它与AOP(面向切面编程)密切相关,可以与AOP框架结合使用,实现对横切关注点的统一处理,如日志记录、事务管理和性能监控等。其次,动态代理可用于远程方法调用,通过代理对象实现跨网络的对象调用。此外,...

    springAOP之代理模式.docx

    springAOP指的是在spring中的AOP,什么是AOP,相对于java中的面向对象(oop),在面向对象中一些公共的行为,像日志记录,权限验证等如果都使用面向对象来做,会在每个业务方法中都写上重复的代码,造成代码的冗余。...

    spring aop 实现源代码--xml and annotation(带lib包)

    在Spring1.2或之前的版本中,实现AOP的传统方式就是通过实现Spring的AOP API来定义Advice,并设置代理对象。Spring根据Adivce加入到业务流程的时机的不同,提供了四种不同的Advice:Before Advice、After Advice、...

    spring AOP代理机制.docx

    sping AOP面向切面的编程,程序运行过程中动态加入所需代码等,对公共的问题进行集中处理,具体的实现有动态代理与静态代理,本文通过对AOP的代理机制,前置、后置、环绕、异常的通知进行了综合总结和运用!

    springmvc+hibernate 日志管理工具

    功能日志:基于java aop思想设计,通过Spring advisorAutoProxy(自动代理)实现controller过滤代理拦截,并提供拦截filter过滤,支持spring EL表达式。 数据日志:设计中提供数据日志注入接口,管理数据日志注入,...

    spring hibernate 日志管理插件

    功能日志:基于java aop思想设计,通过Spring advisorAutoProxy(自动代理)实现controller过滤代理拦截,并提供拦截filter过滤,支持spring EL表达式。 数据日志:设计中提供数据日志注入接口,管理数据日志注入,...

    Spring AOP运用Spring AOP技术,要求包含前置通知、后置通知、环绕通知、返回通知、异常返回通知。

    3、使用JDK动态代理技术,对目标类UserDaoImpl生成代理类,此时目标类中的方法成为切入点,通过代理技术,将切面类的通知织入到目标类的方法中,要求在切入点的前后分别加上切面类的审核方法和日志记录方法。...

    eclair:Java Spring库用于声明式日志记录

    Eclair-用于AOP日志记录的Java Spring库。 提供用于注释性方法执行的声明式日志记录的注释。 包括用于批注处理的抽象,简单的实现以及具有自动配置的Spring Boot启动程序。 特征 Spring AOP检测到的事件日志记录:...

    Springaop原理及各种应用场景

    AOP是...实现的关键就在于AOP框架自动创建的AOP代理,AOP代理则可分为静态代理和动态代理两大类,其中静态代理是指使用 AOP框架提供的命令进行编译,从而在编译阶段就可生成AOP代理类,因此也称为编译

    关于AOP在JS中的实现与应用详解

    AOP (面向切面编程),缩写为Aspect Oriented Programming,意为:面向切面编程,通过预编译方式和运行期动态代理实现程序功能的统一维护的一种技术。AOP是OOP的延续,是软件开发中的一个热点,也是JAVA 中Spring...

    automon:Automon将AOP(AspectJ)的功能与用于声明式监视Java代码,JDK和第3方库的监视或日志记录工具结合在一起

    Automon将AOP(AspectJ)的功能与用于声明式监视以下内容的监视工具或日志记录工具结合在一起: 您的Java代码, JDK, 您的应用程序使用的所有jar。 Automon当前可使用的一些监视工具为:JAMon,JavaSimon,...

    proxytoys:有用的Java代理工具集合

    ProxyToys用来代理生成,就像Jakarta Commons Logging用来记录日志一样-一种用于代理创建的精简实现中立API。 使用标准代理还是使用CGLIB是单行代码更改。特征API兼容的代理工厂提供者: JDK的标准代理CGLIB实施...

    weaverl:Erlang 遇到 AOP

    更具体地说,这个项目的目标是允许 Erlang/OTP 开发人员通过将横切关注点(例如日志记录)放入单独的文件(即模块)又名方面来保持他们的应用程序干净和易于理解。 在撰写本文时, weaverl 仅支持 。 到目前为止,...

    【白雪红叶】JAVA学习技术栈梳理思维导图.xmind

    关于java程序员发展需要学习的路线整理集合 技术 应用技术 计算机基础知识 cpu mem disk net 线程,进程 第三方库 poi Jsoup zxing Gson 数据结构 树 栈 链表 队列 图 操作系统 linux 代码控制...

Global site tag (gtag.js) - Google Analytics