在java开发中,有很多地方都会用到代理,代理也有很多的方式可以实现,这里先介绍java自带的实现接口InvocationHandler方式:
首先来举一个例子,有这么一个类:BookFacadeProxy
import java.lang.reflect.InvocationHandler; import java.lang.reflect.Method; import java.lang.reflect.Proxy; /** * JDK动态代理代理类 * * @author student * * */ public class BookFacadeProxy implements InvocationHandler { private Object target; /** * 绑定委托对象并返回一个代理类 * @param target * @return */ public Object bind(Object target) { this.target = target; //取得代理对象 return Proxy.newProxyInstance(target.getClass().getClassLoader(), target.getClass().getInterfaces(), this); //要绑定接口(这是一个缺陷,cglib弥补了这一缺陷) } @Override /** * 调用方法 */ public Object invoke(Object proxy, Method method, Object[] args) throws Throwable { Object result=null; System.out.println("事物开始"); //执行方法 result=method.invoke(target, args); System.out.println("事物结束"); return result; } }
又有这么一个实例类:
public class BookFacadeImpl implements BookFacade { @Override public void addBook() { System.out.println("增加图书方法。。。"); } public void removeBook(){ System.out.println("移除图书方法..."); } }
这就是代理的一个简单实现,测试一下:
public static void main(String[] args) { BookFacadeProxy proxy = new BookFacadeProxy(); BookFacade bookProxy = (BookFacade) proxy.bind(new BookFacadeImpl()); bookProxy.addBook(); bookProxy.removeBook(); /*CGlibProxy proxy = new CGlibProxy(); Train t = (Train) proxy.getProxy(Train.class); t.move(); t.stop();*/ }
输出:
事物开始
增加图书方法。。。
事物结束
事物开始
移除图书方法...
事物结束
这就是代理的简单实现,在实际开发中,当我们想调用别人的方法之后或者之前加一些自己的东西,那么就可以通过代理来实现,下面介绍一个完整实例:
首先写一个实现InvocationHandler接口的类,
public abstract class MyInterfaceProxyHandler<T> implements InvocationHandler{ protected T t; public void setT(T t){ this.t = t; } @Override public Object invoke(Object proxy, Method method, Object[] args) throws Throwable { Object result = beforeCalled(proxy, method, args); if(result == null){ result = method.invoke(t, args); } afterCalled(result); return result; } protected abstract Object beforeCalled(Object proxy, Method method, Object[] args); protected abstract void afterCalled(Object result); @SuppressWarnings({ "hiding", "unchecked" }) protected <T> T createProxy(){ return (T) Proxy.newProxyInstance(t.getClass().getClassLoader(), t.getClass().getInterfaces(), this); } }
然后写一个实现类:
package com.shjv.scs.proxy; import java.lang.reflect.Method; import java.util.HashMap; import java.util.Map; import com.shjv.scs.cm.dao.dev.DevBasicInfoDAO; import com.shjv.scs.cm.service.dev.DevService; import com.shjv.scs.dev.DevType; import com.shjv.scs.domain.dev.DevConmmonInfo; import com.shjv.scs.mediation.enumdef.MediationEnum.IecTeleControlActionType; import com.shjv.scs.mediation.enumdef.MediationEnum.IecTeleControlType; import com.shjv.scs.plsc.msg.PlscSignalValueUtil; import com.shjv.scs.plsc.protocol.plsc.executor.IecPlscTeleControl; import com.shjv.tdscdma.omc.common.lm.OMCLog; import com.shjv.tdscdma.omc.common.lm.OMCLogFactory; import com.shjv.tdscdma.omc.server.adapter.protocol.iec.iec104.constant.IecConstant.TeleControlType; public class DevServiceProxy extends MyInterfaceProxyHandler<DevService> { private OMCLog log = OMCLogFactory.getOMCLog(DevServiceProxy.class); private DevBasicInfoDAO devBasicInfoDAO; @Override protected Object beforeCalled(Object proxy, Method method, Object[] args) { Object result = null; try { if ("operateDev".equals(method.getName())) { } } @Override protected void afterCalled(Object result) { } public void setDevBasicInfoDAO(DevBasicInfoDAO devBasicInfoDAO) { this.devBasicInfoDAO = devBasicInfoDAO; } @Override public void setT(DevService t) { super.setT(t); } @SuppressWarnings("unchecked") @Override public DevService createProxy() { return super.createProxy(); } }
然后在spring配置文件中注入属性
<bean id="devServiceFactory" class="com.shjv.scs.proxy.DevServiceProxy">
<property name="t" ref="devService"/>
<property name="devBasicInfoDAO" ref="devBasicInfoDAO"/>
</bean>
并通过工厂方法来获取
<bean id="devServiceProxy" factory-bean="devServiceFactory" factory-method="createProxy">
</bean>
这样就可以实现代理,可以代理属性中的一切方法,当然以前获取属性的地方需要改成获取devServiceProxy,这样才能完成代理