Bootstrap

Spring AOP三种实现方式

AOP应用场景及原理

AOP适合于那些具有横切逻辑的应用:如性能监测,访问控制,事务管理、缓存、对象池管理以及日志记录。AOP将这些分散在各个业务逻辑中的代码通过横向切割的方式抽取到一个独立的模块中。AOP 实现的关键就在于 AOP 框架自动创建的 AOP 代理,AOP 代理则可分为静态代理和动态代理两大类,其中静态代理是指使用 AOP 框架提供的命令进行编译,从而在编译阶段就可生成 AOP 代理类,因此也称为编译时增强;而动态代理则在运行时借助于 JDK 动态代理、CGLIB 等在内存中“临时”生成 AOP 动态代理类,因此也被称为运行时增强。
AOP用来封装横切关注点,具体可以在下面的场景中使用
Authentication 权限
Caching 缓存
Context passing 内容传递
Error handling 错误处理
Lazy loading 懒加载
Debugging 调试
logging, tracing, profiling and monitoring 记录跟踪 优化 校准
Performance optimization 性能优化
Persistence 持久化
Resource pooling 资源池
Synchronization 同步
Transactions 事务

AOP相关概念

Aop又叫面向切面编程,其中“通知”是切面的具体实现,分为before(前置通知)、after(后置通知)、around(环绕通知)
三个注解的区别:@Before是在所拦截方法执行之前执行一段逻辑。@After 是在所拦截方法执行之后执行一段逻辑。@Around是可以同时在所拦截方法的前后执行一段逻辑。

pointcut“切入点”表达式

例如定义切入点表达式 execution (* com.sample.service.impl...(..))
execution()是最常用的切点函数,其语法如下所示:
整个表达式可以分为五个部分:
1、execution(): 表达式主体。
2、第一个号:表示返回类型,号表示所有的类型。
3、包名:表示需要拦截的包名,后面的两个句点表示当前包和当前包的所有子包,com.sample.service.impl包、子孙包下所有类的方法。
4、第二个号:表示类名,号表示所有的类。
5、(..):最后这个星号表示方法名,号表示所有的方法,后面括弧里面表示方法的参数,两个句点表示任何参数。

实现方式

实现方式一(在XML文档中声明)

    <aop:config>
        <!-- 切入的内容 -->
        <aop:aspect ref="MyLog">
            <!-- 切入的位置,切入点 -->
            <aop:pointcut id="point1" expression="execution(* SpringAOPTest.MyBean.*(..)) "/> 
            <aop:after method="logEnd" pointcut-ref="point1"/>
            <aop:before method="logHead" pointcut-ref="point1"/>       
        </aop:aspect>
    </aop:config>

实现方式二(注解方式)

注意:需要在XML文档中加入,这样系统就会自动寻找进行

@Aspect
public class AOPLog {
    @Before("execution(* SpringAOPTest.MyBean.*(..))")
    public void logHead(){
        System.out.println("....AOPLog I'm head....");
    }
    @After("execution(* SpringAOPTest.MyBean.*(..))")
    public void logEnd(){
        System.out.println("....AOPLog I'm End....");
    }
}

等同于

@Aspect
public class AOPLog {
    @Pointcut("execution(* SpringAOPTest.MyBean.*(..))")
    private void show(){}
    @Before("show()")
    public void logHead(){
        System.out.println("....AOPLog I'm head....");
    }
    @After("show()")
    public void logEnd(){
        System.out.println("....AOPLog I'm End....");
    }
}

通过实现的方式三

public class ImplementsLog implements MethodBeforeAdvice{
    @Override
    public void before(Method method, Object[] os, Object o) throws Throwable {
        System.out.println("hello implements MethodBeforeAdvice ");        
    }
}
<bean id="ImLog" class="SpringAOPTest.ImplementsLog"/>

    <aop:config>
      <aop:pointcut id="point1" expression="execution(* SpringAOPTest.MyBean.*(..)) "/> 
      <aop:advisor advice-ref="ImLog" pointcut-ref="point1"/>  
    </aop:config>

悦读

道可道,非常道;名可名,非常名。 无名,天地之始,有名,万物之母。 故常无欲,以观其妙,常有欲,以观其徼。 此两者,同出而异名,同谓之玄,玄之又玄,众妙之门。

;