需求:现有一个业务Bean(PersonServiceBean),我们需要为PersonServiceBean中的业务方法进行拦截,进行切面编程。
PersonService.java
package com.risetek.service;
public interface PersonService {
public abstract void add();
public abstract void delete();
}
PersonServiceImpl.java
package com.risetek.service.impl;
import com.risetek.service.PersonService;
public class PersonServiceBean implements PersonService {
@Override
public void add(){
System.out.println("add...");
}
@Override
public void delete(){
System.out.println("delete...");
}
}
利用Proxy类创建目标对象代理:
PersonServiceBeanProxyFactory.java
import java.lang.reflect.InvocationHandler;
import java.lang.reflect.Method;
import java.lang.reflect.Proxy;
import com.risetek.service.PersonService;
import com.risetek.service.impl.PersonServiceBean;
public class PersonServiceBeanProxyFactory implements InvocationHandler{
//目标对象
private PersonServiceBean targetObject;
public PersonService getProxyInstence(PersonServiceBean object){
this.targetObject = object;
//通过Proxy类的newProxyInstance方法创建目标对象代理
//三个参数分别为1.目标对象的类加载器。2.目标对象的接口。3.拦截到方法后的回调对象(回调对象必须实现InvocationHandler接口)
//Proxy.newProxyInstance()方法创建的代理对象实现了目标对象所有的接口,因此可以将代理对象强制转换成目标对象的接口类型
return (PersonService) Proxy.newProxyInstance(object.getClass().getClassLoader(), object.getClass().getInterfaces(),this);
}
//实现InvocationHandler接口方法,该方法会拦截目标对象的方法,进行回调
@Override
public Object invoke(Object proxy, Method method, Object[] args)
throws Throwable {
//do something...
//将方法委派给目标对象执行
method.invoke(this.targetObject, args);
//do something...
return null;
}
}
这样我们在客户端就可以使用工厂方法创建代理对象了。
public class TestDemo {
@Test
public void testProxy() {
PersonService personService = new PersonServiceBeanProxyFactory().getProxyInstence(new PersonServiceBean());
personService.add();
}
}
由于Proxy对象的创建代理方法中要使用到目标对象的接口,因此需要进行拦截的业务Bean必须实现接口,如果业务bean没有实现任何接口,则不能用该方法创建代理对象。