一导入包
Spring框架中的cglib包
这时候不需要目标类和代理类的接口了
public class Person {
private Long pid;
private String pname;
public Long getPid() {
return pid;
}
public void setPid(Long pid) {
this.pid = pid;
}
public String getPname() {
return pname;
}
public void setPname(String pname) {
this.pname = pname;
}
}
public class PersonDaoImpl{
public void savePerson() {
System.out.println("save person");
}
public void updatePerson() {
System.out.println("update person");
}
public void deletePerson() {
System.out.println("delete person");
}
public List<Person> getPerson() {
Person person = new Person();
person.setPid(1L);
person.setPname("aaa");
List<Person> personList = new ArrayList<Person>();
personList.add(person);
for(Person person2:personList){
System.out.println(person2.getPname());
}
return personList;
}
}
public class Transaction {
public void beginTransaction(){
System.out.println("begin transaction");
}
public void commit(){
System.out.println("commit");
}
}
public class PersonDaoInteceptor implements MethodInterceptor{
private Transaction transaction;
private Object target;
public PersonDaoInteceptor(Transaction transaction,Object target){
this.transaction = transaction;
this.target = target;
}
public Object createProxy(){
Enhancer enhancer = new Enhancer();
enhancer.setSuperclass(this.target.getClass());//设置目标类为代理类的父类
enhancer.setCallback(this);//设置拦截器为回调函数
return enhancer.create();
}
@Override
public Object intercept(Object arg0, Method method, Object[] arg2,
MethodProxy arg3) throws Throwable {
Object obj;
String methodName = method.getName();
if("savePerson".equals(methodName)||
"updatePerson".equals(methodName)||
"deletePerson".equals(methodName)){
this.transaction.beginTransaction();
obj = method.invoke(this.target, arg2);//调用目标类的目标方法
this.transaction.commit();
}else{
obj = method.invoke(this.target, arg2);//调用目标类的目标方法
}
return obj;
}
}
public class PersonDaoTest {
@Test
public void test(){
Transaction transaction = new Transaction();
PersonDaoImpl target = new PersonDaoImpl();
PersonDaoInteceptor inteceptor = new PersonDaoInteceptor(transaction, target);
PersonDaoImpl proxy = (PersonDaoImpl)inteceptor.createProxy();
proxy.updatePerson();
}
}
cglib和jdk的动态代理:
* jdk
目标类和代理类实现了共同的接口
拦截器必须实现InvocationHandler接口,而这个接口中invoke方法体的内容就是代理对象方法体的内容
当客户端用代理对象调用方法的时候,invoke方法执行
* cglib
目标类是代理类的父类
拦截器必须实现MethodInterceptor接口,而接口中的intercept方法就是代理类的方法体
使用字节码增强机制创建代理对象的