Spring 02AOP

Spring Stu AOP

1. AOP

1.1 AOP介绍:实现原理,术语

 面向切面编程—介绍

在这里插入图片描述
 原理:
aop底层将采用代理机制进行实现。
接口+实现类:Spring擦爱用jdk的动态代理
实现类:spring采用cglib字节码增强

 术语:
1.Taget: -----目标类:需要被代理的类 例如:userService
2. Joinpoint----链接点:所谓链接点是指那些可能被拦截到的方法。例如:目标类的方法
3.PointCut------切入点:已经被增强的链接点。例如:addUser();
4.advice------通知/增强:增强的代码,例如after,before();
5.Weaving----织入:是指把增强的advice应用到目标类对象target创建代理对象proxy的过程。
6.proxy 代理
7.Aspect—切面:切入点pointcut和通知advice的结合
一个pointcut和advice就能组成一个面
在这里插入图片描述

1.2 手动方式实现
1.2.1 JDK动态代理

 Jdk动态代理 对“装饰者”设计模式的简化。前提:必须有接口

  1. 目标类:接口+实现类
  2. 切面类:用于存通知MyAspect
  3. 工厂类:工厂生成代理
  4. 测试
public class MyBeanFactory {

	public static UserService  craetService() {
		//1目标类
		UserService userService=new UserServiceImpl();
		//2切面类
		MyAspect myAspect =new MyAspect();
		/*
		 * 3代理类
		 * 
		 * 参数1:类加载器,动态代理类运行时创建,任何类都需要类加载器将其加载到内存
		 *        一般当前类.class.getClassLoader
		 * 参数2:代理类需要实现的所有接口 
		 *       方案1:目标类.getClass().getInterfaces()
		 *       方案2:new Class[]{UserService.class}
		 * 参数3:处理类,接口。匿名内部类
		 *    invoke方法:代理类的每一个方法执行时,都去调用invoke
		 *    参数3.1:Object arg0:代理对象
		 *    参数3.2:Method arg1:代理当前执行方法的描述对像(反射)
		 *            执行方法名:method.getName()
		 *            执行方法:method.invoke(对象,实际参数)
		 *    参数3.3:Object[] arg2:方法实际参数
		 *    
		  */
		UserService proxyService=(UserService)Proxy.newProxyInstance(MyBeanFactory.class.getClassLoader(),
				userService.getClass().getInterfaces(), 
				new InvocationHandler() {
					
					@Override
					public Object invoke(Object arg0, Method arg1, Object[] arg2) throws Throwable {
						//  结合目标类和切面类
						
						//前执行
						myAspect.before();
						//执行目标类的方法
						Object obj=arg1.invoke(userService, arg2);
						//后执行
						myAspect.after();
						return obj;
					}
				});
		return proxyService;
	}
}
1.2.2 CGLIB字节码增强

 没有接口
 采用字节码增强框架,运行的时候创建目标类的子类,从而对目标流泪进行增强。
 导入jar包:
Spring-core…jar 内的asm和cglib

public class MyBeanFactory {

	public static UserServiceImpl  craetService() {
		//1目标类
		UserServiceImpl userService=new UserServiceImpl();
		//2切面类
		MyAspect myAspect =new MyAspect();
	    //3代理类
		  //核心类
		  Enhancer enhancer=new Enhancer();
		  //确定父类
		  enhancer.setSuperclass(userService.getClass());
		  //设置回调函数,MethodInterceptor接口
		  /*intercept和JDK中的invoke()等价
		   * 参数4方法的代理
		   */
		enhancer.setCallback(new org.springframework.cglib.proxy.MethodInterceptor() {
			@Override
			public Object intercept(Object arg0, Method arg1, Object[] arg2, MethodProxy arg3) throws Throwable {
				//前方法
				myAspect.before();
				//执行目标类
				Object obj=arg1.invoke(userService, arg2);
				//后方法
				myAspect.after();
				return obj;
			}
		});
		//3.4创建代理
		  UserServiceImpl proxService=(UserServiceImpl)enhancer.create();
		return proxService;
	}
}
1.2.3 Cglib和jdk动态代理的区别

参考:https://blog.csdn.net/XiYoumengshen/article/details/87909861

1.3 Spring编写代理:半自动

导入jar包:
核心4+1
AOP:A OP联盟、spring-aop
如:
aopalliance.jar—AOP联盟
下载地址:https://mvnrepository.com/artifact/org.aspectj/aspectjrt/1.8.10
aspectjweaver.jar
spring-aop-3.2.13.RELEASE.jar

1.4 Spring Aop编程:全自动【重要】

 从spring容器获得目标类,如果配置aop,spring自动生成代理
 要确定目标类,aspect切入点表达式------导入jar包

 配置bean时需导入命名空间:

xmlns:aop=http://www.springframework.org/schema/aop

bean配置

           <bean id="userServiceId" class="com.spring02.a_proxy.c_spring_aop.UserServiceImpl"></bean>
           <!-- 2创建切面类 (通知) -->
          <bean id="myAspectId" class="com.spring02.a_proxy.c_spring_aop.MyAspect"></bean>
          <!-- 3 aop编程 
               1.导入命名空间
               2.使用<aop:config>进行配置
                 <aop:pointcut >切入点,从目标对象获得具体方法
                 <aop:advisor> 特殊的切面,只有1个通知和一个切入点
                               advice-ref:通知的引用
                               pointcut-ref:切入点的引用
               3.切入点表达式
                   execution(*com.spring02.a_proxy.c_spring_aop.UserServiceImpl.*(..) 
                   execution(*com.spring02.a_proxy.c_spring_aop.*.*(..)  
                                      选择方法 返回值任意  包                                           类名任意 方法名任意 参数任意

          -->
           <aop:config proxy-target-class="true">
               <aop:pointcut expression="execution(* com.spring02.a_proxy.c_spring_aop.*.*(..))" id="mypointCut"/>
            
                <aop:advisor advice-ref="myAspectId" pointcut-ref="mypointCut"/>
          </aop:config>

2. AspectJ

主要用途:自定义开发

2.1切入点表达式【掌握】

1.execution()用于描述方法
语法:execution(修饰符 返回值 包.类.方法(参数)throws异常)
修饰符:Public共有方法
* 任意
返回值:(不能省略)Void String *
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述

2.2AspectJ通知类型

在这里插入图片描述
在这里插入图片描述
 导入jar包4个:aop联盟,spring aop,aspect规范,spring aspect规范

2.3基于xml

1:目标类:接口和实现类
2:切面类:采用aspectj通知名称任意
3:aop编程:通知应用到目标类
2.4基于注解
包:com.spring02.d_aspectj_anno

2.4.1:Spring配置:

aop:aspectj-autoproxy</aop:aspectj-autoproxy> <context:component-scan base-package=“com.spring02.d_aspectj_anno”></context:component-scan>

2.4.2:aop注解总结

@Aspect 声明切面,修饰切面类,获得通知。
通知:

@Before @AfterReturning @Around
@AfterThrowing @After

//声明公共的切入点
@Pointcut(“execution(* com.spring02.d_aspectj_anno.UserServiceImpl.*(…))”)
public void myPointCut() {
}
//使用声明公共的切入点
在通知里:value=“myPointCut()”

参考:
Cglib和jdk动态代理的区别: https://blog.csdn.net/XiYoumengshen/article/details/87909861

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值