zoukankan      html  css  js  c++  java
  • 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
  • 相关阅读:
    微信支付-我遇到的那些问题
    [工作笔记]JDK版本不同导致的SSL异常
    mysql与oracle在groupby语句上的细节差异
    微信js-sdk调用
    循序渐进看Java web日志跟踪(3)-Log4J的使用和配置
    循序渐进看Java web日志跟踪(2)-Java日志API认识
    循序渐进看Java web日志跟踪(1)-Tomcat 日志追踪与配置
    手机号码正则表达式(含虚拟运营商)
    网站URL重写(Java UrlRewrite 的使用)
    TCP/IP提供网络传输速率
  • 原文地址:https://www.cnblogs.com/hahajava/p/9811838.html
Copyright © 2011-2022 走看看