cglib 简单 代理示例-1

引用包cglib-xxx.jar
非Maven项目还需要手动引用包asm-xxx.jar
业务类(不需要定义接口)
cglib代理类(实现接口MethodInterceptor)

异常信息(项目只引用了cglib包,没有引用asm包):

Exception in thread "main" java.lang.NoClassDefFoundError: org/objectweb/asm/Type
    at net.sf.cglib.core.TypeUtils.parseType(TypeUtils.java:184)
    at net.sf.cglib.core.KeyFactory.<clinit>(KeyFactory.java:72)
    at net.sf.cglib.proxy.Enhancer.<clinit>(Enhancer.java:72)
    at com.wzq.demo02.UserServiceCglib.getInstance(UserServiceCglib.java:15)
    at com.wzq.demo02.TestCglib.main(TestCglib.java:6)
Caused by: java.lang.ClassNotFoundException: org.objectweb.asm.Type
    at java.net.URLClassLoader.findClass(Unknown Source)
    at java.lang.ClassLoader.loadClass(Unknown Source)
    at sun.misc.Launcher$AppClassLoader.loadClass(Unknown Source)
    at java.lang.ClassLoader.loadClass(Unknown Source)
    ... 5 more
FATAL ERROR in native method: JDWP on checking for an array class, jvmtiError=JVMTI_ERROR_WRONG_PHASE(112)
JDWP exit error JVMTI_ERROR_WRONG_PHASE(112): on checking for an array class [util.c:1299]

from: https://blog.csdn.net/rain097790/article/details/14168785

public class Person {

    private Integer pid;
    private String pnameString;

    public Person(Integer pid, String pnameString) {
        this.pid = pid;
        this.pnameString = pnameString;
    }

    public Integer getPid() {
        return pid;
    }

    public void setPid(Integer pid) {
        this.pid = pid;
    }

    public String getPnameString() {
        return pnameString;
    }

    public void setPnameString(String pnameString) {
        this.pnameString = pnameString;
    }
}
public class Transaction {

    //开启事物
    public void beginTransaction(){
        System.out.println("--->-非正事(before干正事):--beginTransaction");
    }
    //提交事物
    public void commit(){
        System.out.println("--->-非正事(after干正事):--commit");
    }

}
//此处没有实现PersonDao接口
public class PersonDaoImpl{

    public void savePerson() {
        System.out.println("--->-正事:--savePerson");
    }

    public List<Person> getPersons() {
        List<Person> persons = new ArrayList<>();
        Person person1 = new Person(1, "person1");
        Person person2 = new Person(2, "person2");
        persons.add(person1);
        persons.add(person2);
        return persons;
    }

}
import org.springframework.cglib.proxy.Enhancer;
import org.springframework.cglib.proxy.MethodInterceptor;
import org.springframework.cglib.proxy.MethodProxy;
import java.lang.reflect.Method;
//import net.sf.cglib.proxy.Enhancer;
//import net.sf.cglib.proxy.MethodInterceptor;
//import net.sf.cglib.proxy.MethodProxy;

public class MyInterceptor implements MethodInterceptor {
    private Object personDaoImpl; // personDaoImpl // 目标对象
    private Transaction transaction;

    public MyInterceptor(Object personDaoImpl, Transaction transaction) {
        super();
        System.out.println("=2==构造函数==========================");
        this.personDaoImpl = personDaoImpl;
        this.transaction = transaction;
    }

    /**
     * 产生代理对象
     */
    public Object createProxy(){
        Enhancer enhancer = new Enhancer();//通过类Enhancer创建代理对象
        enhancer.setSuperclass(this.personDaoImpl.getClass());//设置代理对象的父类
        enhancer.setCallback(this);//回调函数  拦截器
        Object poxyer = enhancer.create();//创建代理对象
        System.out.println("-45-->-diy的代理对象(MyInterceptor.class中的diy方法):"+ poxyer);
        return poxyer;
    }

//TODO  arg0:       动态生成的代理对象
//TODO  method :    实际调用的方法
//TODO  arg2:       调用方法入参(当前方法的参数)
//TODO  net.sf.cglib.proxy.MethodProxy:java Method类的代理类,可以实现委托类对象的方法的调用;常用方法:methodProxy.invokeSuper(proxy, args);在拦截方法内可以调用多次
    @Override
    public Object intercept(Object arg0, Method method, Object[] arg2, MethodProxy proxy) throws Throwable {
        System.out.println("=3==进入到了cglibInterceptor的实现方法==========================当前拦截的方法是:"+ method.getName());
        //PersonDaoImpl bean = (PersonDaoImpl)personDaoImpl; // 因为在程序里personDaoImpl(targetObject)为PersonServiceBean
        if(method.getName().equals("savePerson")){
            transaction.beginTransaction();
            Object invoke11 = method.invoke(personDaoImpl, arg2);    //交给目标对象进行处理 --> poxy调用 目标对象的目标方法("savePerson"方法)
//            Object invoke12 = proxy.invoke(arg0, arg2);
            transaction.commit();
            return null;
        }else{ //toString(); getPersons()
            Object invoke21 = method.invoke(this.personDaoImpl, arg2);//poxy调用 目标对象的目标方法
//            Object invoke22 = proxy.invoke(arg0, arg2);
            return invoke21;
        }

    }


}
public class PersonDaoImplTest {

    public static void main(String[] args){
        PersonDaoImpl personDaoImpl = new PersonDaoImpl();
        Transaction transaction = new Transaction();
        System.out.println("=1==start prepare==========================");
        MyInterceptor interceptor = new MyInterceptor(personDaoImpl, transaction);//创建出能生成 目标代理对象的 Class

        PersonDaoImpl proxy = (PersonDaoImpl) interceptor.createProxy();

        proxy.savePerson();

        System.out.println("=21======正事已完成======================");
        for(Person person : proxy.getPersons()){
            System.out.println("-50-->"+person.getPnameString());
        }


    }
}

 结果:

=1==start prepare==========================
=2==构造函数==========================
=3==进入到了cglibInterceptor的实现方法==========================当前拦截的方法是:toString
-45-->-diy的代理对象(MyInterceptor.class中的diy方法):com.wyait.manage.practiceDiy.test3.PersonDaoImpl@2c13da15
=3==进入到了cglibInterceptor的实现方法==========================当前拦截的方法是:savePerson
--->-非正事(before干正事):--beginTransaction
--->-正事:--savePerson
--->-非正事(after干正事):--commit
=21======正事已完成======================
=3==进入到了cglibInterceptor的实现方法==========================当前拦截的方法是:getPersons
-50-->person1
-50-->person2