-
<bean>元素的继承是,<property>属性的拷贝.
-
装饰设计模式:包装类包裹着目标类(构造器里),生成包装类要提供目标类,对外暴露包装类供调用,调包装类的方法时,在目标类执行真正业务方法前后会执行包装类的增强方法
-
静态代理:类似于装饰设计模式,但目标类是通过属性注入到包装类,更安全。代理对象和真实对象的关系在运行前就确定了。以至于有下面缺点:
1.每一个真实对象都得创建一个代理对象。
2.要为每一种方法都进行代理处理。
3.如果接口增加一个方法,所有代理类也需要实现此方法。 -
动态代理类:是在程序运行期间由JVM通过反射等机制动态的生成的。
1、java.lang.reflect.Proxy 类:
Java 动态代理机制生成的所有动态代理类的父类,它提供了一组静态方法来为一组接口动态地生成代理类及其对象。
public static Object newProxyInstance(ClassLoader loader, Class<?>[] interfaces,InvocationHandler hanlder)
方法职责:为指定类加载器、一组接口及调用处理器生成动态代理类实例
2、java.lang.reflect.InvocationHandler接口:调用处理器
public Object invoke(Object proxy, Method method, Object[] args)
方法职责:包括真实业务方法和增强方法的调用,对真实业务方法做增强 -
JDK动态代理:
@Service public class TransactionManageInvocationHandler implements InvocationHandler { @Autowired private PersonDoTx tx; @Autowired private IPersonDoService target; @Override public Object invoke(Object proxy, Method method, Object[] args) throws Throwable { try { tx.begin(); method.invoke(target, args); tx.commit(); } catch (Exception e) { tx.rollback(); } return null; } public IPersonDoService getProxy() { return (IPersonDoService) //this:代理类, 返回动态代理对象 Proxy.newProxyInstance(this.getClass().getClassLoader(), target.getClass().getInterfaces(), this); } }
JDK动态代理总结:
1,代理的对象必须要实现一个接口;
2,每次用都生成一个代理对象
3,动态代理的最小单位是类,所有接口中的方法都会被处理
4,如果只想拦截一部分方法,可以在invoke方法中对要执行的方法名进行判断。
5,拦截器是AOP的一种实现. -
针对于没有接口的类,如何做代理:cglib和javassist都是针对没有接口,做动态代理的.
原理是对指定的目标类生成一个子类,并覆盖其中方法实现增强,但因为采用的是继承,所以不能对final修饰的类进行代理。
CGLIB代理总结:
1,CGLIB可以生成目标类的子类,并重写父类非final修饰符的方法。
2,要求类不能是final的,要拦截的方法要是非final、非static、非private的。
3,动态代理的最小单位是类(所有类中的方法都会被处理);
在Spring中:
若目标对象实现了若干接口,Spring就会使用JDK动态代理。
若目标对象没有实现任何接口,Spring就使用CGLIB库生成目标对象的子类。
对接口创建代理优于对类创建代理,因为会产生更加松耦合的系统,也更符合面向接口编程规范。 -
Spring的AOP:通过动态代理技术,管控对象方法的切面环境,把约定的流程/方法(日志/事务)织入到业务流程前后,
AOP当中的概念:
1、切面(Aspect):切面=切点+通知,AOP会把其定义的内容织入到流程中,相当于拦截器
2、通知(Advice):前置/后置/返回/异常通知
3、切点(Pointcut):告诉AOP什么时候拦截并织入,通过正则表达式限定
4、连接(join point):具体需要拦截的业务方法,通过切点的正则判断
5、织入(Weaving):创建出代理对象并把切面加入到流程的过程。 -
Spring 对 AOP 的支持
1.使用@AspectJ注解开发 Spring AOP
2.使用 XML 配置开发 Spring AOP -
使用@AspectJ注解开发 Spring AOP
1.选择连接点 2.创建切面:用@Aspect 注解一个类,那么 Spring IoC 容器就会认为这是一个切面了;切点+通知: @Aspect public class RoleAspect { @Before (“execution(*com.ssm.aop.service.impl.RoleServiceimpl.printRole(..))”) public void before () { System.out.println (” before ....”); } 3.切点: AspectJ语言execution(<访问修饰符>? <返回类型> <声明类型>? <方法名>(<参数>) <异常>?); execution :代表执行方法的时候会触发;*: 代表任意返回类型的方法;(..) :任意的参数;within():限制连接点匹配指定的包 4.切点的简写: @Pointcut("execution(*com.ssm.aop.service.impl.RoleServiceimpl.printRole (..))") public void prointCut() { } @Before ("prointCut()") public void before () { System.out.println (” before ....”); } 5.注解启动切面 @Configuration @EnableAspectJAutoProxy @ComponentScan (“com.ssm.chapterll.aop”) public class AopConfig { @Bean public RoleAspect getRoleAspect() { return new RoleAspect(); } /** @EnableAspectJAutoProxy代表着启用AspectJ框架的自动代理,这个时候Spring才会生成动态代理对象,进而可以使用AOP,而getRoleAspect 方法,则生成一个切面实例。 <aop:aspectj-autoproxy /> */ 6.xml方式启动切面 <aop:aspectj-autoproxy /> <bean id="roleAspect" class="com.ssm.aop.aspect.RoleAspect"/> <bean id="roleService" class="com.ssm.aop.service.impl.RoleServiceimpl"/〉 </beans> 7.环绕通知 ProceedingJoinPoint 参数,这个参数是 Spring 提供的,使用它可以反射连接点方法, 8.给通知传递参数 @Before(“execution(*com.aop.impl.RoleServiceimpl.printRole(..))"+"&&args(role,sort)")) public void before (Role role , int sort) { System.out.println (” before ....”); } 8.引入
-
使用 XML 配置开发 Spring AOP
xmlns="http://www.springframework.org/schema/beans" xmlns:context="http://www.springframework.org/schema/context" xmlns:aop="http://www.springframework.org/schema/aop" xmlns:tx="http://www.springframework.org/schema/tx" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans.xsd http://www.springframework.org/schema/context http://www.springframework.org/schema/context/spring-context.xsd http://www.springframework.org/schema/aop http://www.springframework.org/schema/aop/spring-aop.xsd http://www.springframework.org/schema/tx http://www.springframework.org/schema/tx/spring-tx.xsd"> <aop:config> <aop:aspect ref="tx" > <aop:pointcut expression="execution(* icbc.proxy.*.*(..))" id="pc"/> <aop:before method="begin" pointcut-ref="pc"/> <aop:after-returning method="commit" pointcut-ref="pc"/> <aop:after-throwing method="rollback" pointcut-ref="pc"/> </aop:aspect> </aop:config> <bean id="tx" class="icbc.proxy.tx.PersonDoTx"> </bean>
-
Spring AOP开发依赖的jar:
spring-aop-4.1.2.RELEASE.jar
com.springsource.org.aopalliance-1.0.0.jar
com.springsource.org.aspectj.weaver-1.6.8.RELEASE.jar -
多个切面顺序,在切面类上贴@Order(1)或<aop: aspect ref=" " order="1"/>
spring-02
最新推荐文章于 2024-02-25 19:15:11 发布