j2ee,设计模式,代理模式

Proxy模式的功能有很多,比如远程代理,用来给远程对象提供一个本地代表;虚代理,用来为创建开大开销的对象提供缓冲,等等。
今天以权限控制为例简单讲讲代理模式。
实现代理模式三种方式:
1、静态代理
2、动态代理
3、Spring中的AOP

1.静态代理
代理从接口出发,这里有个业务组件接口:
package proxy.ttcp;
public interface ICompent{
    public void bus1() ;
    public void bus2() ;
    public void bus3() ;
}

编写代理对象,代理对象实现被代理接口:
package proxy.ttcp;
public class ProxyCompent implements ICompent{
        private ICompent compent;
 public ProxyCompent (ICompent compent){
  this.compent = compent;
 }
 public void check(){
  System.out.println("权限控制。。。") ;
 }
 public void bus1(){
  check() ;
  compent.bus1() ;
 }
 
 public void bus2(){
  check() ;
  ccompent.bus2() ;
 }
 
 public void bus3(){
  check() ;
  compent.bus3() ;
 }

}

编写被代理对象,实现被代理接口:
package proxy.ttcp;
public class Compent implements ICompent{

 public void bus1() {
  // TODO Auto-generated method stub
  System.out.println("ttcp1") ;
 }

 public void bus2() {
  // TODO Auto-generated method stub
  System.out.println("ttcp2") ;
 }

 public void bus3() {
  // TODO Auto-generated method stub
  System.out.println("ttcp3") ;
 }

}

写一个测试类:
package proxy.ttcp;
public class Test{
   public static void main(String []args){
  ICompent proxy = new Proxy(new Compent()) ;
  proxy.bus1() ;
  proxy.bus2() ;
  proxy.bus3() ;
  }

}
这就是静态代理,但是程序规模很大时就胜任不了,接下来便引出动态代理
2.动态代理
结合静态代理的实现机制,抽象出一个泛类代理,也就是说不依赖任何被代理对象的代理实现
设计一个处理被代理对象的类,该类实现InvocationHandler接口:
package dynaProxy.ttcp;
import java.lang.reflect.InvocationHandler;
import java.lang.reflect.*;

public class DynamicProxy implements InvocationHandler {

 private Object obj ;
 public Object bind(Object obj){
  this.obj = obj ;
  return Proxy.newProxyInstance(obj.getClass().getClassLoader(), obj.getClass().getInterfaces(), this) ;
 }
 public Object invoke(Object proxy, Method method, Object[] args)
   throws Throwable {
  // TODO Auto-generated method stub
  try{
   check() ;
   method.invoke(obj, args) ;
  }catch(Exception ex){
   ex.printStackTrace() ;
  }
  return null;
 }
 public void check(){
  System.out.println("验证.....") ;
 }

}

使用Proxy.newProxyInstance静态方法建立一个代理对象,obj.getClass().getInterfaces()
来告知所要代理的接口,通过method.invoke(obj, args) 调用代理对象中的方法,method.invoke
返回的结果也就是代理对象中方法返回的结果。
测试类:
package dynaProxy.ttcp;
import proxy.ttcp.Compent;
import proxy.ttcp.ICompent;

public class Test {

 public static void main(String []args){
  DynamicProxy proxy = new DynamicProxy() ;
  ICompent com = (ICompent)proxy.bind(new Compent()) ;
  com.bus1() ;
  com.bus2() ;
  com.bus3() ;
 }
}

3.AOP
以前置通知为例
被代理接口使用之前的ICompent,接口的实现也使用之前的Compent
编写前置通知,该类实现MethodBeforeAdvice

package aop.ttcp;

import java.lang.reflect.Method;

import org.springframework.aop.MethodBeforeAdvice;

public class AdviceBefore implements MethodBeforeAdvice {

 public void before(Method arg0, Object[] arg1, Object arg2)
   throws Throwable {
  // TODO Auto-generated method stub
  System.out.println("权限验证。。。") ;
 }

 

}

application.xml文件

<?xml version="1.0" encoding="UTF-8"?>
<beans
 xmlns="http://www.springframework.org/schema/beans "
 xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance "
 xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans-2.0.xsd ">
   
    <bean id="beforeAdvice" class="aop.ttcp.AdviceBefore"/>
 <bean id="compent" class="proxy.ttcp.Compent"/>
 <bean id="proxy"
     class="org.springframework.aop.framework.ProxyFactoryBean">
     <!-- 被代理类要实现的接口 -->
     <property name="proxyInterfaces" value="proxy.ttcp.ICompent"/>
     <!--目标对象-->
     <property name="target" ref="compent"/>
     <property name="interceptorNames">
         <list>
             <!--代理对象-->
             <value>beforeAdvice</value>
         </list>
     </property>
 </bean>
</beans>

编写测试类
package tradition.ttcp;

import org.springframework.context.ApplicationContext;
import org.springframework.context.support.ClassPathXmlApplicationContext;

import proxy.ttcp.ICompent;

public class Test {

   public static void main(String []args){
    ApplicationContext context =
      new ClassPathXmlApplicationContext("applicationContext.xml") ;
    ICompent compent = (ICompent)context.getBean("proxy") ;
    compent.bus1() ;
    compent.bus2() ;
    compent.bus3() ;
   }
}

可以看到与之前的静态、动态代理的结果一样
除了前置通知外,还有后置通知,环绕通知等

 

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值