Spring提供俩种方式实现AOP

发布时间 : 星期五 文章Spring提供俩种方式实现AOP更新完毕开始阅读

AOP是Aspect Oriented Programming的缩写,意思是面向方面编程,一种新兴的编程技术。

AOP实际是GoF设计模式的延续,设计模式孜孜不倦追求的是调用者和被调用者之间的解耦,

AOP可以说也是这种目标的一种实现。它可以解决OOP和过程化方法不能够很好解决的横切

(crosscut)问题,

如:事务、安全、日志等横切关注。当未来系统变得越来越复杂,

横切关注点就成为一个大问题的时候,AOP就可以很轻松的解决横切关注点这个问题。

比如有这样一个情景: Java代码

1. public class AccountManager {

2. private static final sysLogger = SystemLogger.getInstance();

3. private AuthorizationManager authMgr = new AuthorizationManager(); 4.

5. public void transferFunds(String from, String to, int amount) {

6. sysLogger.log(\to);

7. if(authMgr.accessAble(from) && authMgr.accessAble(to)) {

8. sysLogger.log(\9. CustomerAccount from = findAccount(from); 10. CustomerAccount to = findAccount(to); 11. from.debit(amount); 12. to.credit(amount); 13. } else {

14. sysLogger.log(\15. }

16. sysLogger.log(\to + \17. } 18.}

这个例子虽然是很好的面向对象代码,但是在业务处理逻辑中夹杂这日志处理和权限判断,变得复杂混乱.

在 AOP 中,正交关注点(如安全和日志记录)被识别为系统中的常见横切关注

点。说它们是横切,

是因为它们总是切入模块(如包、类和代码文件)的多个单位。也许横切关注点可能不是核心业务逻辑的一部分,但是它们是应用程序的基本部分。

AOP的实现主要是通过方法的拦截实现.在不使用AOP框架的情况下,我们可以通过JDK提供的动态代理来实现方法的拦截

注意:使用JDK提供的动态代理实现 要求我们的目标对象必须实现接口

IUserBean接口 Java代码

1. package com.royzhou.aop; 2.

3. public interface IUserBean { 4.

5. public void getUser(); 6.

7. public void addUser(); 8.

9. public void updateUser(); 10.

11. public void deleteUser(); 12.}

IUserBean实现类 UserBean.java Java代码

1. package com.royzhou.aop; 2.

3. public class UserBean implements IUserBean { 4.

5. private String user = null; 6.

7. public UserBean() { 8. } 9.

10. public UserBean(String user) { 11. this.user = user; 12. } 13.

14. public void setUser(String user) {

15. this.user = user; 16. } 17.

18. public void addUser() {

19. System.out.println(\20. } 21.

22. public void deleteUser() {

23. System.out.println(\24. } 25.

26. public void getUser() {

27. System.out.println(\28. } 29.

30. public void updateUser() {

31. System.out.println(\32. } 33.}

我们希望在UserBean执行方法之前先检查userName是不是为空,以此做为权限判断.

当然我们可以在没个方法里面去加这些判断,但是这需要为每个方法都添加同样的判断,维护不便.

使用JDK提供的动态代理技术可以很方便的实现上面的需求: 通过java.lang.reflect.Proxy;提供的

public static Object newProxyInstance(ClassLoader loader, Class[] interfaces, InvocationHandler h)

方法可以生成一个动态代理对象 其中

loader是类装载器

interfaces是目标对象实现的一系列接口

h是一个实现InvocationHandler接口的类,我们对代理对象的所有操作都经过它处理

这样我们就可以拦截到UserBean的方法,在方法执行前先判断是否有权限,如果有则执行方法,

没有权限的话就不执行方法.

编写我们的代理类: JDKProxy.java Java代码

1. package com.royzhou.aop; 2.

3. import java.lang.reflect.InvocationHandler; 4. import java.lang.reflect.Method; 5. import java.lang.reflect.Proxy; 6.

7. public class JDKProxy implements InvocationHandler { 8.

9. private Object targetObject; 10.

11. public Object createProxyObject(Object targetObject) { 12. this.targetObject = targetObject; 13. //生成代理对象

14. return Proxy.newProxyInstance(this.targetObject.getClass().getClassLoader(),this.targetObject.getClass().getInterfaces(),this); 15. } 16.

17. public Object invoke(Object proxy, Method method, Object[] args) throws Throwable {

18. UserBean userBean = (UserBean) targetObject; 19. String userName = userBean.getUserName(); 20. Object result = null; 21. //权限判断

22. if(userName!=null && !\23. //调用目标对象的方法

24. result = method.invoke(targetObject, args); 25. }

26. return result; 27. } 28.}

通过调用createProxyObject可以生成代理对象, 编写测试类如下: Java代码

1. package com.royzhou.aop; 2.

3. public class TestProxy { 4.

5. public static void main(String[] args) { 6. JDKProxy jProxy = new JDKProxy();

联系合同范文客服:xxxxx#qq.com(#替换为@)