Spring入门第三讲 Spring中的代理 静态代理 动态代理(JDK代理) cglib代理(字节码增强) Spring中的AOPspring的静态代理和动态代理
概念:代理即在访问真正的对象之前和之后所做的业务处理的对象
以事务的操作为例讲解:
静态代理
代理对象和真实的对象需要实现同一个接口
目标对象类 public class UserDaoImpl implements IUserDao { @Override public int saveUser() { //System.out.println("--开启事务--"); System.out.println("--添加用户--"); //System.out.println("--关闭事务--"); return 0; } @Override public int delUser() { //System.out.println("--开启事务--"); System.out.println("--删除用户--"); //System.out.println("--关闭事务--"); return 0; } } 代理对象类 public class ProxyUserDaoImpl implements IUserDao{ //UserDaoImpl userDao = new UserDaoImpl(); IUserDao userDao; public ProxyUserDaoImpl(IUserDao userDao){ this.userDao = userDao; } @Override public int saveUser() { System.out.println("--开启事务--"); userDao.saveUser(); System.out.println("--关闭事务--"); return 0; } @Override public int delUser() { System.out.println("--开启事务--"); userDao.delUser(); System.out.println("--关闭事务--"); return 0; } } 测试类 @Test public void test(){ IUserDao userDao = new ProxyUserDaoImpl(new UserDaoImpl2()); userDao.delUser(); userDao.saveUser(); }动态代理(JDK代理)
在程序运行期间,动态的创建代理对象
//目标对象类与上述相同 //测试方法 @Test public void test2(){ //真实对象 IUserDao userDao = new UserDaoImpl(); //创建代理对象 //ClassLoader 加载真实对象的class文件 //Class<?>[] 真实对象所实现的所有接口 IUserDao proxy = (IUserDao) Proxy.newProxyInstance( userDao.getClass().getClassLoader(), userDao.getClass().getInterfaces(), //代理对象要做的事情 new InvocationHandler(){ //proxy 代理对象 //method 目标对象中的方法的描述方法 //args 目标对象中方法的参数 @Override public Object invoke(Object proxy, Method method, Object[] args) throws Throwable { System.out.println("开启事务"); //每个要代理的方法都会执行 //通过反射机制,找到要执行的dao里面的方法 Object obj = method.invoke(userDao, args); System.out.println("关闭事务"); return obj; } } ); proxy.delUser(); proxy.saveUser(); }问题:必须要有接口
cglib代理(字节码增强)
导入jar,只需要提供要代理的类即可
jar:asm.jar cglib.jar或者使用Spring-core.jar(其中包含的有)
1、面向切面编程:采用横向抽取的方式,在程序运行的过程中,动态的向目标对象中织入要增强的代码。底层采用动态代理方式(JDK代理和cglib代理)
2、应用场景
事务管理、日志、性能监控等…
3、术语解释
target:目标对象
advice:通知(增强代码)
joinpoint:连接点,可能要添加增强代码的方法
pointcut:切入点,要添加增强代码的方法
weaving:织入,将增强代码添加到切入点的过程
aspect:切面,切入点和增强代码之间形成的虚拟的面
4、案例–给删除方法添加事务管理,使用aspectj框架而非Spring aop
步骤:
a)创建项目,导入jar。
4+1 core context bean spel jcl
spring-aop.jar 基于aspectj实现的
spring-aspects.jar aspectj的规则
aspectjweaver.jar 织入的技术
aopalliance.jar 设置通知的规则
b)创建目标类和通知类
public class UserServiceImpl implements UserService{ @Override public int saveUser() { userDao.saveUser(); return 0; } @Override public int delUser() { userDao.delUser(); return 0; } } public class MyAdvice{ //JoinPoint用于获取目标对象中的相关信息 public void before(JoinPoint joinPoint){ System.out.println("添加事务"); } public void after(){ System.out.println("关闭事务"); } public void afterReturning(){ System.out.println("后置通知"); } public void afterThrowing(){ System.out.println("异常通知"); } //环绕通知,必须手动调用目标对象的方法 public void around(ProceedingJoinPoint joinPoint){ try{ System.out.println("前置"); joinPoint.proceed(); System.out.println("返回"); }catch(){ System.out.println("异常"); }finally{ System.out.println("后置通知"); } } } <!--创建目标对象--> <bean id="userService" ></bean> <!--创建增强类对象--> <bean id="myAdvice" ></bean> <!--将通知织入到目标对象上 aop:config属性 proxy-target- true代表强制使用cglib --> <aop:config> <!--切入点:配置要向什么地方添加增强代码 expression:execution(返回值类型 包名 类名 方法名(参数,...)) * service..*(..) --> <aop:pointcut expression="execution(* service..*(..))" id="myPointcut"/> <!--切面:添加什么,如何添加--> <aop:aspect ref="myAdvice"> <!--前置通知--> <!--<aop:before method="before" pointcut-ref="myPointcut"/>--> <!--后置通知--> <!--<aop:after method="after" pointcut-ref="myPointcut"/>--> <!--返回通知--> <!--<aop:after-returning method="afterReturning" pointcut-ref="myPointcut"/>--> <!--异常通知--> <!--<aop:after-throwing method="afterThrowing" pointcut-ref="myPointcut"/>--> <!--环绕通知--> <aop:around method="around" pointcut-ref="myPointcut"/> </aop:aspect> </aop:config> //测试类 @RunWith(SpringJUnit4ClassRunner.class) @ContextConfiguration(locations="classpath:applicationContext.xml") public class AopTest{ @Autowired UserService userService; @Test public void test(){ userService.saveUser(); userService.delUser(); } }java中的静态代理、jdk动态代理和cglib动态代理jdk cglib动态代理
Jdk代理和CGLIB代理的区别cglib代理和jdk动态代理区别
最详细的代理讲解--JDK动态代理和cglib代理cglib代理和jdk动态代理区别
Java JDK中的静态代理、动态代理&Cglib动态代理jdk cglib动态代理
动态代理:JDK动态代理和CGLIB代理的区别cglib代理和jdk动态代理区别
总结:静态代理、jdk动态代理、cglib代理cglib代理和jdk动态代理区别
Java动态代理的两种实现方法:JDK动态代理和CGLIB动态代理jdk静态代理和动态代理
JDK动态代理和 CGLIB代理cglib代理和jdk动态代理区别