SpringAop应用二

本章内容:
1.Aop是什么
2.Aop的应用场景
3.Spring Aop和Aop有什么关系
4.SpringAop与AspectJ的关系
5.SpringAop支持AspectJ
6.Spring Aop的概念
7.Aop的表达式

<一>:Aop是什么

与OOP对比,面向切面,传统的OOP开发中的代码逻辑是自上而下的
比如:浏览器发送请求到Servlet,Serverlet进行一些封装到Service,Service处理逻辑,Dao与数据库交互
而这些过程会产生一些横切性问题,这些横切性的问题和我们的主业务逻辑关系不大,比如说:日志的记录,权限验证
这些横切性问题不会影响到主逻辑实现,但是会散落到代码的各个部分,难以维护。
AOP是处理一些横切性问题,AOP的编程思想就是把这些问题和主业务逻辑分开,
达到与主业务逻辑解耦的目的。使代码的重用性和开发效率更高。

<二>:Aop的应用场景

 - 日志记录 
 - 权限验证 
 - 效率检查 
 - 事务管理 
 - exception

<三>Spring Aop和Aop有什么关系:

Aop是一种思想,SpringAop是这种思想的一种实现,还有下面我们要说的AspectJ
IOC是一种思想,依赖注入,依赖查找,都是对这个思想的实现

<四>SpringAop与AspectJ的关系

按道理来说SpringAop和AspectJ是不同的实现,应该属于竞争关系,
但是SpringAop的语法比较难接受,所以它使用的是AspectJ的语法,但是是自己的实现!
所以我们导包的时候是AspectJ,而不是Spring

<五>SpringAop支持AspectJ

步骤一:

使用Java Configuration启用@AspectJ支持:
要使用Java @Configuration启用@AspectJ支持,请添加@EnableAspectJAutoProxy注释
@Configuration
@ComponentScan("com.aop")
@EnableAspectJAutoProxy(proxyTargetClass = false)
public class Appconfig {
}
使用XML配置启用@AspectJ支持
要使用基于xml的配置启用@AspectJ支持,可以使用aop:aspectj-autoproxy元素

<aop:aspectj-autoproxy/>

步骤二:

2、声明一个Aspect
申明一个@Aspect注释类,并且定义成一个bean交给Spring管理。

@Component
@Aspect
public class LubanAspectj{
}

步骤三

3、申明一个pointCut
切入点表达式由@Pointcut注释表示。切入点声明由两部分组成:一个签名包含名称和任何参数,
以及一个切入点表达式,该表达式确定我们对哪个方法执行感兴趣。

@Pointcut("execution(* transfer(..))")// 切入点表达式
private void anyOldTransfer() {}// 切入点签名

切入点确定感兴趣的 join points(连接点),从而使我们能够控制何时执行通知。
Spring AOP只支持Spring bean的方法执行 join points(连接点),
所以你可以将切入点看作是匹配Spring bean上方法的执行。
@Component
@Aspect
public class LubanAspectj {
    @Pointcut("execution(* com.aop.dao.*.*(..))")
    public void pointCutWithExecution(){}
    

步骤四:

4、申明一个Advice通知
advice通知与pointcut切入点表达式相关联,
并在切入点匹配的方法执行@Before之前、@After之后或前后运行。【通知的详细在下一篇博客】
@Before("pointCutWithExecution()")
    public void  before(){
        System.out.println("before");
    }

在这里插入图片描述
<六>:Spring Aop的概念

aspect:一定要给spring去管理  抽象的概念  aspectj->类  
pointcut:切点表示连接点的集合  ------------------->           相当于表
  (我的理解:PointCut是JoinPoint的谓语,这是一个动作,主要是告诉通知连接点在哪里,切点表达式决定 JoinPoint 的数量)
Joinpoint:连接点   目标对象中的方法 ---------------->    相当于表中的记录
  (我的理解:JoinPoint是要关注和增强的方法,也就是我们要作用的点)
Weaving :把代理逻辑加入到目标对象上的过程叫做织入
target 目标对象 原始对象
aop Proxy 代理对象  包含了原始对象的代码和增加后的代码的那个对象
advice:通知    (作用的位置 + logic)

<七>:Aop的表达式

execution
用于匹配方法执行 join points连接点,最小粒度方法,在aop中主要使用。

execution(modifiers-pattern? ret-type-pattern declaring-type-pattern?name-pattern(param-pattern) throws-pattern?)
这里问号表示当前项可以有也可以没有,其中各项的语义如下
modifiers-pattern:方法的可见性,如public,protected;
ret-type-pattern:方法的返回值类型,如int,void等;
declaring-type-pattern:方法所在类的全路径名,如com.spring.Aspect;
name-pattern:方法名类型,如buisinessService();
param-pattern:方法的参数类型,如java.lang.String;
throws-pattern:方法抛出的异常类型,如java.lang.Exception;

@Pointcut("execution(* com.aop.dao.*.*(..))") 
    public void pointCutWithExecution(){}
within
/*表达式的最小粒度为类
 within与execution相比,粒度更大,仅能实现到包和接口、类级别。而execution可以精确到方法的返回值,参数个数、修饰符、参数类型等*/
@Pointcut("within(com.chenss.dao.*)")//匹配com.chenss.dao包中的任意方法
@Pointcut("within(com.chenss.dao..*)")//匹配com.chenss.dao包及其子包中的任意方法
args
/* args表达式的作用是匹配指定参数类型和指定参数数量的方法,与包名和类名无关*/
 @Pointcut("args(java.lang.String)")
    public void pointCutWithArgs(){}
annotation
   /**
     * 使用annotation来进行筛选
     * 如果这个方法有被注解注释就可以进行增强
     */
    @Pointcut("@annotation(com.aop.anno.Luban)")
    public void pointCutAnnotation(){}
this
 /**
     * this是代理对象,和IndexDao是否类型相等,相同就会增强该方法,我们要看采用的是什么代理方式
     */
    @Pointcut("this(com.aop.dao.IndexDao)")
    public void pointCutThis(){}

这就牵扯到@EnableAspectJAutoProxy(proxyTargetClass = true),proxyTargetClass = false使用jdk动态代理,
默认是false,那么创建的代理对象和IndexDao都只是实现了Dao接口,类型不会相同
你们有没有想过为什么JDK动态代理,目标对象必须要实现接口
Class[]clazz=new Class[]{Dao.class};
byte[] bytes = ProxyGenerator.generateProxyClass("LubanAa", clazz);
File file=new File("G:\\text.claas");
try {
    FileOutputStream outputStream=new FileOutputStream(file);
    outputStream.write(bytes);
    outputStream.flush();
} catch (FileNotFoundException e) {
    e.printStackTrace();
} catch (IOException e) {
    e.printStackTrace();
}
反编译我们就会发现,代理对象继承了Proxy,java是单继承,所以目标对象要实现接口,

如果proxyTargetClass = true使用CGLIB动态代理,采用的是继承,产生目标对象的子类,那么目标对象就会个IndexDao类型相同
target
/**
     * 目标对象是否和IndexDao类型相同
     */
    @Pointcut("target(com.aop.dao.IndexDao)")
    public void pointCuttarget(){}

明天会具体详细的写一篇动态代理的博客!!!
如有错误,请指正哦!
在这里插入图片描述

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值