当目标类实现了接口,我们可以使用jdk的Proxy来生成代理对象。
下面我们使用jdk的aop技术为 PersionServiceBean (它本身实现了一个接口) 来产生一个代理对象
主要业务:当user对象不为空的时候我们才调用业务方法,否则什么也不做
步骤:
(1) 建立接口类 PersionSevice
package cn.com.xinli.service; public interface PersionSevice { public void save(String name); public void update(String name, Integer personid); public String getPersonName(Integer personid); }
(2)建立实现类 PersionServiceBean
package cn.com.xinli.service.impl; import org.apache.log4j.Logger; import org.springframework.stereotype.Service; import cn.com.xinli.service.PersionSevice; @Service public class PersionServiceBean implements PersionSevice { Logger log=Logger.getLogger(PersionServiceBean.class); private String user = null; public String getUser() { return user; } public PersionServiceBean(){} public PersionServiceBean(String user){ this.user = user; } public String getPersonName(Integer personid) { System.out.println("我是getPersonName()方法"); return "xxx"; } public void save(String name) { System.out.println("我是save()方法"); } public void update(String name, Integer personid) { System.out.println("我是update()方法"); } }
(3). 建立代理工厂,必须实现 InvocationHandler 接口
package cn.com.xinli.aop; import java.lang.reflect.InvocationHandler; import java.lang.reflect.Method; import java.lang.reflect.Proxy; import cn.com.xinli.service.impl.PersionServiceBean; public class JDKProxyFactory implements InvocationHandler{ private Object targetObject; public Object createProxyIntance(Object targetObject){ this.targetObject = targetObject; return Proxy.newProxyInstance(this.targetObject.getClass().getClassLoader(), this.targetObject.getClass().getInterfaces(), this); } public Object invoke(Object proxy, Method method, Object[] args) throws Throwable {//环绕通知 PersionServiceBean bean = (PersionServiceBean) this.targetObject; Object result = null; if(bean.getUser()!=null){ //..... advice()-->前置通知 try { result = method.invoke(targetObject, args); // afteradvice() -->后置通知 } catch (RuntimeException e) { //exceptionadvice()--> 例外通知 }finally{ //finallyadvice(); -->最终通知 } } return result; } }
(4) 测试
JDKProxyFactory factory = new JDKProxyFactory(); PersionSevice service = (PersionSevice) factory.createProxyIntance(new PersionServiceBean("hxl")); service.save("ss");
(5) 结果 当传入字符传 "huxl" 的时候 打印出 我是save()方法, 当不传字符的时候什么也没有打印.
总结:
a. 使用jdk的 Proxy类实现代理 体现了面向接口编程,它必须要求需要代理的对象实现了接口,代理工厂实现了 InvocationHandler ,否存我们就要使用另外一种技术 CGLIB实现AOP功能
b.代码解释
public class JDKProxy implements InvocationHandler { private Object targetObject;//代理的目标对象 public Object createProxyInstance(Object targetObject){ this.targetObject = targetObject; /* * 第一个参数设置代码使用的类装载器,一般采用跟目标类相同的类装载器 * 第二个参数设置代理类实现的接口 * 第三个参数设置回调对象,当代理对象的方法被调用时,会委派给该参数指定对象的invoke方法 */ return Proxy.newProxyInstance(this.targetObject.getClass().getClassLoader(), this.targetObject.getClass().getInterfaces(), this); } public Object invoke(Object proxy, Method method, Object[] args) throws Throwable { return method.invoke(this.targetObject, args);//把方法调用委派给目标对象 } } 当目标类实现了接口,我们可以使用jdk的Proxy来生成代理对象。
