温故知新:spring_04静态代理实现AOP

spring的另一个重要特性是AOP(Aspect Oriented Programming)面向切面的编程,spring的AOP特性使得对于使用了该特性的项目的可维护性,易拓展性和开发难易度等等都有了不同程度的改善。AOP特性能够使得项目中的某些操作,在执行到某一个指定环节的时候,可以额外的去执行开发者指定的操作,这些操作往往都是具有共通性,而且可能和操作本身所包含的业务逻辑没有直接的关系,比如对数据库的访问,涉及变更数据库内容的操作需要精准的记录日志;每当产生异常或者错误信息的时候,也需要记录错误信息;对服务器敏感资源进行访问的时候需要对用户的权限进行校验等。在哪些环节添加处理,做怎样的处理,都可以由开发者自定义,十分灵活,而且在开发业务逻辑和流程的时候大可不必去考虑这些共同性质的处理,让主要精力都投入在业务的实现上,这样一来,开发效率会大大提高。

先从一个静态代理的例子来感受一下这种切入式的编程
IUserDao
1 package org.duyt.dao;
2 public interface IUserDao {
3     public void add();
4 }
UserDao
 1 package org.duyt.dao.impl;
 2 
 3 import org.duyt.dao.IUserDao;
 4 import org.springframework.context.annotation.Scope;
 5 import org.springframework.stereotype.Repository;
 6 
 7 @Repository("userDao")
 8 @Scope("singleton")
 9 public class UserDao implements IUserDao {
10     public void add() {
11         System.out.println("用户增加方法");
12     }
13 }
14 
一个很单纯的接口实现。倘若这就是一个成品了,测试通过没有问题,可以上线使用。一段时间之后,需要加入日志的功能,那么问题来了,挖掘机哪...噢不对,该如何添加呢?
或许会马上想到,直接该啊。那么问题又来了,挖...噢不,直接修改的话,代码就需要测试,而且万一需要修改的地方很多呢,岂不是很痛苦,况且直接修改源代码还违背了OCP原则,绝对不推荐。这时候就可以考虑使用代理类来给源代码增加新功能。
代理,望文生义,白话就是“你要做的事儿我不仅能给你做了,而且除此之外我还能多做别的”,定义一个UserProxyDao
 1 package org.duyt.dao.impl;
 2 
 3 import javax.annotation.Resource;
 4 
 5 import org.duyt.dao.IUserDao;
 6 import org.duyt.util.Logger;
 7 import org.springframework.context.annotation.Scope;
 8 import org.springframework.stereotype.Repository;
 9 
10 @Repository("userProxyDao")
11 @Scope("singleton")
12 public class UserProxyDao implements IUserDao {
13 
14     @Resource
15     private IUserDao userDao;
16     
17     public void add() {
18         Logger.info("使用代理,为用户增加方法添加日志");
19         userDao.add();
20 
21     }
22 
23 }
24 
在代理中,将需要拓展功能的对象作为代理的属性注入,然后在需要拓展的方法前后追加需要的功能。在此之后,在给service的IuserDao对象注入实例的时候,要使用代理的对象@Resource(name = "userProxyDao"),测试一下
 1 package org.duyt.test;
 2 
 3 import org.duyt.action.UserAction;
 4 import org.junit.Test;
 5 import org.springframework.beans.factory.BeanFactory;
 6 import org.springframework.context.support.ClassPathXmlApplicationContext;
 7 
 8 public class IocTest {
 9 
10     private BeanFactory factory = new ClassPathXmlApplicationContext("beans.xml");
11     
12     @Test
13     public void test(){
14         //测试代理依赖注入
15         UserAction ua = (UserAction) factory.getBean("userAction");
16         ua.addUser();
17     }
18     
19 }
20 
结果:
使用代理,为用户增加方法添加日志
用户增加方法

由于IOC和AOP的特性,你会发现你要做的更改十分的少,仅仅只是新增了一个代理类,并修改了注入的对象。虽然静态的代理可以实现我们的需求,但是毕竟不灵活,一旦修改涉及的方法和类一多,那简直就是纯体力活了,一个类的拓展就需要对应一个代理类,一个代理类中还需要涵盖所有需要拓展的方法,并且保证原有功能不受影响,如此一来,功能拓展这一举动就需要投入极大的成本,入不敷出。

posted on 2014-11-04 14:57 都较瘦 阅读(150) 评论(0)  编辑  收藏 所属分类: containerFramework


只有注册用户登录后才能发表评论。


网站导航:
 
<2024年12月>
24252627282930
1234567
891011121314
15161718192021
22232425262728
2930311234

导航

统计

公告

博客定位:囿于目前的水平,博客定位在记录自己的学习心得和随手的练习

常用链接

留言簿

随笔分类

随笔档案

文章分类

文章档案

搜索

最新评论

阅读排行榜

评论排行榜