引用包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