当目标类实现了接口,我们可以使用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来生成代理对象。