AOP面向切面编程(一)

来源:互联网 发布:linux中echo n 编辑:程序博客网 时间:2024/04/28 16:26

在这一篇博客,主要介绍AOP面向切面编程基础,为什么需要面向切面编程。通过一个简单的程序来实现,这次依然使用的是模拟Spring时的项目架构,项目代码可以参见点击打开链接这篇博客。这是一个使用Spring容器作为bean管理的项目。

1、现在的业务需求是,要求在向数据库保存用户的时候,这一动作前后都要有时间上的日志记录。如果有项目源码的话,可以在源码直接加入逻辑,到达想要的效果。

public class UserDAOImpl implements UserDAO {public void save(User user) {System.out.println("Before saving user" + System.currentTimeMillis());System.out.println("user saved!");System.out.println("After saving user" + System.currentTimeMillis());}}

2、考虑现在有这样一种情况,如果这是一个曾经的项目,现在我们无法获取源码,只有一系列的class文件和类的使用说明doc文档,现在我们应该怎么办?

我们可以利用Spring的自动注入的功能,重新定义一个满足业务需求的UserDAO实体,继承自已有的UserDAOImpl,扩展其方法,然后注入到需要的类中

public class UserDAOImpl2 extends UserDAOImpl {@Overridepublic void save(User user) {System.out.println("Before saving user" + System.currentTimeMillis());super.save(User user);System.out.println("After saving user" + System.currentTimeMillis());}}
Spring的配置文件bean.xml也要修改
<beans><bean id="u" class="com.bjsxt.dao.impl.UserDAOImpl" /><bean id="u2" class="com.bjsxt.dao.impl.UserDAOImpl" /><bean id="userService" class="com.bjsxt.service.UserService" ><property name="userDAO" bean="u2"/></bean></beans>
此时,userService中使用的UserDAO就能在写入到数据库前后进行日志记录了。

3、通常提倡的是慎用继承,能不用就不用。因为使用继承的话,耦合性太强,不够灵活,当父类如果变了的话,子类也就必须跟着要变。而且,继承了这个父类的话,就不能继承其他的类了。可以使用组合的方式去代替继承。需要注意的是,所有的这些原始的工具类,或者新的进行代理的工具类,都要实现同一个接口,这样,在注入的时候才能自由的切换。

public class UserDAOImpl2 implements UserDAO {private UserDAO u = new UserDAOImpl();public void save(User user) {System.out.println("Before saving user" + System.currentTimeMillis());u.save(user);System.out.println("After saving user" + System.currentTimeMillis());}}
Spring的配置文件bean.xml也要修改

<beans><bean id="u" class="com.bjsxt.dao.impl.UserDAOImpl" /><bean id="u2" class="com.bjsxt.dao.impl.UserDAOImpl" /><bean id="userService" class="com.bjsxt.service.UserService" ><property name="userDAO" bean="u2"/></bean></beans>

4、按照上边的方法,我们能够初步完成业务要求。现在考虑,如果要求对所有的save方法,无论是saveUser,还是saveProduct等等,都需要加入日志信息,前后一共500多个方法,那么你要对500个bean重新进行组合吗?这时就需要用到了动态代理。详情可以参照下一篇博客。