Spring提供俩种方式实现AOP.docx

上传人:b****5 文档编号:6361845 上传时间:2023-01-05 格式:DOCX 页数:43 大小:28.72KB
下载 相关 举报
Spring提供俩种方式实现AOP.docx_第1页
第1页 / 共43页
Spring提供俩种方式实现AOP.docx_第2页
第2页 / 共43页
Spring提供俩种方式实现AOP.docx_第3页
第3页 / 共43页
Spring提供俩种方式实现AOP.docx_第4页
第4页 / 共43页
Spring提供俩种方式实现AOP.docx_第5页
第5页 / 共43页
点击查看更多>>
下载资源
资源描述

Spring提供俩种方式实现AOP.docx

《Spring提供俩种方式实现AOP.docx》由会员分享,可在线阅读,更多相关《Spring提供俩种方式实现AOP.docx(43页珍藏版)》请在冰豆网上搜索。

Spring提供俩种方式实现AOP.docx

Spring提供俩种方式实现AOP

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

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("transfer funds from " + from + " to " + to);  

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

8.            sysLogger.log("access successfully");  

9.            CustomerAccount from = findAccount(from);  

10.            CustomerAccount to = findAccount(to);  

11.            from.debit(amount);  

12.            to.credit(amount);  

13.        } else {  

14.            sysLogger.log("access deny");  

15.        }  

16.        sysLogger.log("transfer funds from " + from + " to " + to + " $" + amount + " successfully!

");  

17.    }  

18.}  

publicclassAccountManager{

privatestaticfinalsysLogger=SystemLogger.getInstance();

privateAuthorizationManagerauthMgr=newAuthorizationManager();

publicvoidtransferFunds(Stringfrom,Stringto,intamount){

sysLogger.log("transferfundsfrom"+from+"to"+to);

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

sysLogger.log("accesssuccessfully");

CustomerAccountfrom=findAccount(from);

CustomerAccountto=findAccount(to);

from.debit(amount);

to.credit(amount);

}else{

sysLogger.log("accessdeny");

}

sysLogger.log("transferfundsfrom"+from+"to"+to+"$"+amount+"successfully!

");

}

}

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

在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.}  

packagecom.royzhou.aop;

publicinterfaceIUserBean{

publicvoidgetUser();

publicvoidaddUser();

publicvoidupdateUser();

publicvoiddeleteUser();

}

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("this is addUser() method!

");  

20.    }  

21.  

22.    public void deleteUser() {  

23.        System.out.println("this is deleteUser() method!

");  

24.    }  

25.  

26.    public void getUser() {  

27.        System.out.println("this is getUser() method!

");  

28.    }  

29.  

30.    public void updateUser() {  

31.        System.out.println("this is updateUser() method!

");  

32.    }  

33.}  

packagecom.royzhou.aop;

publicclassUserBeanimplementsIUserBean{

privateStringuser=null;

publicUserBean(){

}

publicUserBean(Stringuser){

this.user=user;

}

publicvoidsetUser(Stringuser){

this.user=user;

}

publicvoidaddUser(){

System.out.println("thisisaddUser()method!

");

}

publicvoiddeleteUser(){

System.out.println("thisisdeleteUser()method!

");

}

publicvoidgetUser(){

System.out.println("thisisgetUser()method!

");

}

publicvoidupdateUser(){

System.out.println("thisisupdateUser()method!

");

}

}

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

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

使用JDK提供的动态代理技术可以很方便的实现上面的需求:

通过java.lang.reflect.Proxy;提供的

publicstaticObjectnewProxyInstance(ClassLoaderloader,

 Class

>[]interfaces,

 InvocationHandlerh)

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

其中

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 && !

"".equals(userName)) {  

23.            //调用目标对象的方法  

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

25.        }   

26.        return result;  

27.    }  

28.}  

packagecom.royzhou.aop;

importjava.lang.reflect.InvocationHandler;

importjava.lang.reflect.Method;

importjava.lang.reflect.Proxy;

publicclassJDKProxyimplementsInvocationHandler{

privateObjecttargetObject;

publicObjectcreateProxyObject(ObjecttargetObject){

this.targetObject=targetObject;

//生成代理对象

returnProxy.newProxyInstance(this.targetObject.getClass().getClassLoader(),this.targetObject.getClass().getInterfaces(),this);

}

publicObjectinvoke(Objectproxy,Methodmethod,Object[]args)throwsThrowable{

UserBeanuserBean=(UserBean)targetObject;

StringuserName=userBean.getUserName();

Objectresult=null;

//权限判断

if(userName!

=null&&!

"".equals(userName)){

//调用目标对象的方法

result=method.invoke(targetObject,args);

}

returnresult;

}

}

通过调用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();  

7.        IUserBean userBean = (IUserBean) jProxy.createProxyObject(new UserBean("royzhou"));  

8.        userBean.addUser();  

9.    }  

10.}  

packagecom.royzhou.aop;

publicclassTestProxy{

publicstaticvoidmain(String[]args){

JDKProxyjProxy=newJDKProxy();

IUserBeanuserBean=(IUserBean)jProxy.createProxyObject(newUserBean("royzhou"));

userBean.addUser();

}

}

执行成功后输出:

thisisaddUser()method!

再次修改测试类:

Java代码

1.package com.royzhou.aop;  

2.  

3.public class TestProxy {  

4.      

5.    public static void main(String[] args) {  

6.        JDKProxy jProxy = new JDKProxy();  

7.        IUserBean userBean = (IUserBean) jProxy.createProxyObject(new UserBean());  

8.        userBean.addUser();  

9.    }  

10.}  

packagecom.royzhou.aop;

publicclassTestProxy{

publicstaticvoidmain(String[]args){

JDKProxyjProxy=newJDKProxy();

IUserBeanuserBean=(IUserBean)jProxy.createProxyObject(newUserBean());

userBean.addUser();

}

}

即当用户没有权限时,控制台不输出东西,说明我们拦截方法对其做的权限判断生效了.

从上面这个例子可以成功拦截了调用的方法并对其做了相应的处理

如果不使用JDK提供的Proxy类

通过cglib创建代理类,好处是不要求我们的目标对象实现接口

Enhancerenhancer=newEnhancer();

enhancer.setSuperclass(this.targetObject.getClass());

enhancer.setCallback(this);//回调,参数是一个实现MethodInterceptor接口的类,我们对代理对象的所有操作都经过它处理

returnenhancer.create();//创建代理对象

修改UserBean去掉IUserBean接口

Java代码

1.package com.royzhou.aop;  

2.  

3.public class UserBean {  

4.      

5.    private String userName = null;  

6.      

7.    public UserBean() {  

8.    }  

9.  

10.    public UserBean(String userName) {  

11.        this.userName = userName;  

12.    }  

13.  

14.    public void addUser() {  

15.        System.out.println("this is addUser() method!

");  

16.    }  

17.  

18.    public void deleteUser() {  

19.        System.out.println("this is deleteUser() method!

");  

20.    }  

21.  

22.    public void getUser() {  

23.        System.out.println("this is getUser() method!

");  

24.    }  

25.  

26.    public void updateUser() {  

27.        System.out.println("this is updateUser() method!

");  

28.    }  

29.  

30.    public String getUserName() {  

31.        return userName;  

32.    }  

33.  

34.    public void setUserName(String userName) {  

35.        this.userName = userName;  

36.    }  

37.}  

packagecom.royzhou.aop;

publicclassUserBean{

privateStringuserName=null;

publicUserBean(){

}

publicUserBean(StringuserName){

this.userName=userName;

}

publicvoidaddUser(){

System.out.println("thisisaddUser()method!

");

}

publicvoiddeleteUser(){

System.out.println("thisisdeleteUser()method!

");

}

publicvoidgetUser(){

System.out.println("thisisgetUser()method!

");

}

publicvoidupdateUser(){

System.out.println("thisisupdateUser()method!

");

}

publicStringgetUserName(){

returnuserName;

}

publicvoidsetUserName(StringuserName){

this.userName=userName;

}

}

通过cglib创建代理类

CGLibProxy.java

Java代码

1.package com.royzhou.aop;  

2.  

3.import java.lang.reflect.Method;  

4.  

5.import net.

展开阅读全文
相关资源
猜你喜欢
相关搜索

当前位置:首页 > 法律文书 > 判决书

copyright@ 2008-2022 冰豆网网站版权所有

经营许可证编号:鄂ICP备2022015515号-1