ServletAOP动态代理的使用

来源:互联网 发布:砍刀能在淘宝上买么 编辑:程序博客网 时间:2024/05/24 02:22

代理是java程序中常用的一种开发思想,其中动态代理是切面编程中使用的,动态代理的概念为:通过使用代理类接口InvocationHandler实现对所有被代理类方法的调用,但除了调用被代理类的方法外,也会调用其他实例化在代理类中的方法,从而实现切面编程的思想。

  用不恰当的比喻来解释的话:代理类就好比是苹果和三星的维修部门,苹果是一个接口,使用苹果手机的人是继承了苹果接口的具体实现类类;三星是一个其他的接口,使用三星的是继承了三星的具体实现类,如果苹果和三星只能使用自己的维修部门(代理类)那么这种方式就是静态代理,但是考虑到成本(代码重复)问题,所以两家想要共用一个维修部(代理)。在这个维修部(代理)中,当使用苹果的人来维修时,那么维修部将手机交给苹果的维修师进行维修,当使用三星的人来维修时,维修部就将手机交给三星的维修师。这就是动态代理的使用。切面编程思想就是,不管谁来维修手机,手机交给维修师以前都要在维修部前台的员工那里做一个登记、维修好后又需要在维修部会计那里算一下费用。这样将被代理的方法夹在了其他方法中间,这就是切面编程的思想。为了方便理解请分析下图:

由上图可以看出,当使用苹果的人去维修时,测试类会创建对应的实例对象,并调用代理类。当代理类被调用时,此时就会执行维修部的方法,而在执行“进行维修”方法以前,代理类会默认先执行“前台接待”方法,在执行完“进行维修”后,代理类又会执行“会计收费”,这就是动态代理与切面编程的使用。

下面通过代码来进行熟悉,代码的运行需求:在执行登录login()或regise()方法以前要先执行过滤方法,这样有效的防止传入错误信息。

/**
  * @author admin
 *这是登录的接口
 */
public interface FileterTest {
public void login();//验证登录
public void regise();//验证注册
}

/**
  * @author admin
  * 这个是登录的实现类
  */
public class LoginTest implements FileterTest {
@Override
public void login() {
System.out.println("我是被代理的方法,我要登录");
}

@Override
public void regise() {
System.out.println("I want to regise");
}
}

/**
  * @author admin
  *这是切面编程中的切入方法,在执行被代理方法以前先将数据进行过滤
 */
public class Filter{
public void filter(){
System.out.println("我是过滤器,我属于切面编程,在执行被代理方法前要先执行我的方法");
}
}

/**
 * @author admin
 * 这是动态代理类
 */
public class My_InvocationHandler implements InvocationHandler {
Object obj;
//获取被代理类的实例对象
public void setObj(Object obj){
this.obj=obj;
}
@Override
public Object invoke(Object proxy, Method method, Object[] args) throws Throwable {
Filter f=new Filter();
f.filter();//切面方法,在执行被代理方法以前会执行过滤

Object object=method.invoke(obj, args);//invoke()在执行时会默认执行被代理的方法
return object;
}
}
class MyProxy{
public static Object getProxy(Object obj){
My_InvocationHandler myInHandler=new My_InvocationHandler();
myInHandler.setObj(obj);
//Proxy.newProxyInstance()三个参数分别为:调用需要被代理类的类名、调用别代理类的接口、调用要使用的代理类对象
return Proxy.newProxyInstance(obj.getClass().getClassLoader(), obj.getClass().getInterfaces(), myInHandler);

}
}


public class Test {
public static void main(String[] args) {
LoginTest login=new LoginTest();//创建登录的实例化对象
//将要被代理的类方法添加到代理类中
FileterTest fil=(FileterTest) MyProxy.getProxy(login);
//在执行的login()与regise()方法时,都会先执行过滤方法filter()
fil.login();
fil.regise();
}


}


希望对大家学习切面编程以及动态代理有所帮助,欢迎各位对我不足的地方提出建议。

0 0
原创粉丝点击