发布时间 : 星期五 文章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();