Java动态代理实现与增强机制解析

需积分: 12 0 下载量 52 浏览量 更新于2024-08-05 收藏 3KB MD 举报
"本文主要介绍了Java中的静态代理和动态代理技术,探讨了它们的基本原理和实现过程。" 在Java编程中,代理模式是一种常见的设计模式,它允许我们为一个对象提供一个代理,以控制对该对象的访问或增加额外的功能。代理模式在软件开发中尤其在服务层(如JavaEE环境)扮演着重要角色,如事务管理、日志记录等。 #### 静态代理 静态代理是手动编写代理类来实现与目标类相同的接口。在静态代理中,我们首先定义一个接口,然后让目标类和代理类都实现这个接口。代理类的主要任务是在调用目标类的方法前后添加额外的逻辑,比如在`addUser`方法中添加事务处理。 ```java // 接口 interface UserService { int addUser(User u); } // 目标类 class UserServiceImpl implements UserService { public int addUser(User u) { // 实现业务逻辑 } } // 代理类 class UserServiceProxy implements UserService { private UserService target = new UserServiceImpl(); @Override public int addUser(User u) { Transaction tx = new Transaction(); tx.openTx(); int result = target.addUser(u); tx.commitTx(); return result; } } ``` 在上面的代码中,代理类`UserServiceProxy`持有目标对象`UserService`的引用,并在其`addUser`方法中调用目标对象的同名方法,同时添加了事务处理的逻辑。这样做可以使得业务逻辑与事务管理相分离,符合面向切面编程(AOP)的理念。 #### 动态代理 动态代理则更加灵活,不需要手动编写代理类。Java提供了一个内置的API,即`java.lang.reflect.Proxy`,可以帮我们动态地创建代理对象。动态代理的核心在于生成代理类对象的`Proxy.newProxyInstance()`方法。 ```java // 目标对象 UserService target = new UserServiceImpl(); // 代理对象 UserService us = (UserService) Proxy.newProxyInstance( target.getClass().getClassLoader(), target.getClass().getInterfaces(), new TxInvocationHandler(target) ); // 调用方法 int count1 = us.addUser(newUser(111, "小A")); ``` 这里,`Proxy.newProxyInstance()`接收三个参数:目标类的类加载器、目标类实现的接口列表以及一个实现了`java.lang.reflect.InvocationHandler`接口的处理器对象。当我们通过代理对象调用方法时,实际上是调用了`InvocationHandler`的`invoke()`方法,我们可以在这个方法中加入额外的逻辑,比如事务处理。 动态代理的好处在于,我们不再需要为每个目标类创建一个代理类,只需要一个通用的`InvocationHandler`即可。这使得代码更简洁,更易于维护,特别是在需要对多个类进行相同增强的情况下。 总结来说,静态代理适用于目标类较少且对代理类功能定制要求较高的场景,而动态代理则适用于目标类众多或者增强逻辑相对通用的情况,它提供了更大的灵活性和代码复用性。在JavaEE环境中,动态代理常用于实现AOP框架,如Spring的AOP模块,以方便地实现切面编程。

java.lang.ExceptionInInitializerError at sun.reflect.NativeConstructorAccessorImpl.newInstance0(Native Method) at sun.reflect.NativeConstructorAccessorImpl.newInstance(NativeConstructorAccessorImpl.java:62) at sun.reflect.DelegatingConstructorAccessorImpl.newInstance(DelegatingConstructorAccessorImpl.java:45) at java.lang.reflect.Constructor.newInstance(Constructor.java:422) at org.junit.runners.BlockJUnit4ClassRunner.createTest(BlockJUnit4ClassRunner.java:195) at org.junit.runners.BlockJUnit4ClassRunner$1.runReflectiveCall(BlockJUnit4ClassRunner.java:244) at org.junit.internal.runners.model.ReflectiveCallable.run(ReflectiveCallable.java:12) at org.junit.runners.BlockJUnit4ClassRunner.methodBlock(BlockJUnit4ClassRunner.java:241) at org.junit.runners.BlockJUnit4ClassRunner.runChild(BlockJUnit4ClassRunner.java:70) at org.junit.runners.BlockJUnit4ClassRunner.runChild(BlockJUnit4ClassRunner.java:50) at org.junit.runners.ParentRunner$3.run(ParentRunner.java:238) at org.junit.runners.ParentRunner$1.schedule(ParentRunner.java:63) at org.junit.runners.ParentRunner.runChildren(ParentRunner.java:236) at org.junit.runners.ParentRunner.access$000(ParentRunner.java:53) at org.junit.runners.ParentRunner$2.evaluate(ParentRunner.java:229) at org.junit.runners.ParentRunner.run(ParentRunner.java:309) at org.junit.runner.JUnitCore.run(JUnitCore.java:160) at com.intellij.junit4.JUnit4IdeaTestRunner.startRunnerWithArgs(JUnit4IdeaTestRunner.java:69) at com.intellij.rt.junit.IdeaTestRunner$Repeater$1.execute(IdeaTestRunner.java:38) at com.intellij.rt.execution.junit.TestsRepeater.repeat(TestsRepeater.java:11) at com.intellij.rt.junit.IdeaTestRunner$Repeater.startRunnerWithArgs(IdeaTestRunner.java:35) at com.intellij.rt.junit.JUnitStarter.prepareStreamsAndStart(JUnitStarter.java:235) at com.intellij.rt.junit.JUnitStarter.main(JUnitStarter.java:54) Caused by: org.apache.ibatis.exceptions.PersistenceException: ### Error building SqlSession. ### The error may exist in mappers/categoryMapper.xml ### Cause: org.apache.ibatis.builder.BuilderException: Error parsing SQL Mapper Configuration. Cause: java.io.IOException: Could not find resource mappers/categoryMapper.xml at org.apache.ibatis.exceptions.ExceptionFactory.wrapException(ExceptionFactory.java:30) at org.apache.ibatis.session.SqlSessionFactoryBuilder.build(SqlSessionFactoryBuilder.java:82) at org.apache.ibatis.session.SqlSessionFactoryBuilder.build(SqlSessionFactoryBuilder.java:66) at Test.<clinit>(Test.java:19) ... 23 more Caused by: org.apache.ibatis.builder.BuilderException: Error parsing SQL Mapper Configuration. Cause: java.io.IOException: Could not find resource mappers/categoryMapper.xml at org.apache.ibatis.builder.xml.XMLConfigBuilder.parseConfiguration(XMLConfigBuilder.java:115) at org.apache.ibatis.builder.xml.XMLConfigBuilder.parse(XMLConfigBuilder.java:95) at org.apache.ibatis.session.SqlSessionFactoryBuilder.build(SqlSessionFactoryBuilder.java:80) ... 25 more Caused by: java.io.IOException: Could not find resource mappers/categoryMapper.xml at org.apache.ibatis.io.Resources.getResourceAsStream(Resources.java:114) at org.apache.ibatis.io.Resources.getResourceAsStream(Resources.java:100) at org.apache.ibatis.builder.xml.XMLConfigBuilder.mapperElement(XMLConfigBuilder.java:338) at org.apache.ibatis.builder.xml.XMLConfigBuilder.parseConfiguration(XMLConfigBuilder.java:113) ... 27 more

2023-07-13 上传

index.vue:201 Uncaught (in promise) TypeError: Cannot read properties of undefined (reading 'type') at _callee$ (index.vue:201:1) at tryCatch (regeneratorRuntime.js:44:1) at Generator.eval (regeneratorRuntime.js:125:1) at Generator.eval [as next] (regeneratorRuntime.js:69:1) at asyncGeneratorStep (asyncToGenerator.js:3:1) at _next (asyncToGenerator.js:22:1) at eval (asyncToGenerator.js:27:1) at new Promise (<anonymous>) at eval (asyncToGenerator.js:19:1) at VueComponent.handleNodeClick (index.vue:227:1) _callee$ @ index.vue:201 tryCatch @ regeneratorRuntime.js:44 eval @ regeneratorRuntime.js:125 eval @ regeneratorRuntime.js:69 asyncGeneratorStep @ asyncToGenerator.js:3 _next @ asyncToGenerator.js:22 eval @ asyncToGenerator.js:27 eval @ asyncToGenerator.js:19 handleNodeClick @ index.vue:227 handleCurrentChange @ index.vue:197 invokeWithErrorHandling @ vue.runtime.esm.js:3971 invoker @ vue.runtime.esm.js:1188 invokeWithErrorHandling @ vue.runtime.esm.js:3971 Vue.$emit @ vue.runtime.esm.js:2874 eval @ element-ui.common.js:1116 eval @ vue.runtime.esm.js:4097 flushCallbacks @ vue.runtime.esm.js:4019 Promise.then(异步) timerFunc @ vue.runtime.esm.js:4044 nextTick @ vue.runtime.esm.js:4109 queueWatcher @ vue.runtime.esm.js:3346 Watcher.update @ vue.runtime.esm.js:3584 Dep.notify @ vue.runtime.esm.js:710 reactiveSetter @ vue.runtime.esm.js:4380 proxySetter @ vue.runtime.esm.js:5158 handleCurrentChange @ element-ui.common.js:1069 invokeWithErrorHandling @ vue.runtime.esm.js:3971 invoker @ vue.runtime.esm.js:1188 invokeWithErrorHandling @ vue.runtime.esm.js:3971 Vue.$emit @ vue.runtime.esm.js:2874 onPagerClick @ element-ui.common.js:547 invokeWithErrorHandling @ vue.runtime.esm.js:3971 invoker @ vue.runtime.esm.js:1188 original_1._wrapper @ vue.runtime.esm.js:7265

2023-06-12 上传
2023-06-05 上传

index.vue:202 Uncaught (in promise) TypeError: Cannot read properties of undefined (reading 'type') at _callee$ (index.vue:202:1) at tryCatch (regeneratorRuntime.js:44:1) at Generator.eval (regeneratorRuntime.js:125:1) at Generator.eval [as next] (regeneratorRuntime.js:69:1) at asyncGeneratorStep (asyncToGenerator.js:3:1) at _next (asyncToGenerator.js:22:1) at eval (asyncToGenerator.js:27:1) at new Promise (<anonymous>) at eval (asyncToGenerator.js:19:1) at VueComponent.handleNodeClick (index.vue:228:1) _callee$ @ index.vue:202 tryCatch @ regeneratorRuntime.js:44 eval @ regeneratorRuntime.js:125 eval @ regeneratorRuntime.js:69 asyncGeneratorStep @ asyncToGenerator.js:3 _next @ asyncToGenerator.js:22 eval @ asyncToGenerator.js:27 eval @ asyncToGenerator.js:19 handleNodeClick @ index.vue:228 handleSizeChange @ index.vue:191 invokeWithErrorHandling @ vue.runtime.esm.js:3971 invoker @ vue.runtime.esm.js:1188 invokeWithErrorHandling @ vue.runtime.esm.js:3971 Vue.$emit @ vue.runtime.esm.js:2874 handleChange @ element-ui.common.js:982 invokeWithErrorHandling @ vue.runtime.esm.js:3971 invoker @ vue.runtime.esm.js:1188 invokeWithErrorHandling @ vue.runtime.esm.js:3971 Vue.$emit @ vue.runtime.esm.js:2874 handleOptionSelect @ select.js:1945 invokeWithErrorHandling @ vue.runtime.esm.js:3971 Vue.$emit @ vue.runtime.esm.js:2874 dispatch @ emitter.js:29 selectOptionClick @ option.js:383 click @ option.js:230 invokeWithErrorHandling @ vue.runtime.esm.js:3971 invoker @ vue.runtime.esm.js:1188 original_1._wrapper @ vue.runtime.esm.js:7265 index.vue:201

2023-06-13 上传