• Spring AOP


    1.Spring AOP 中的基本概念

    a.连接点(Joinpoint

    在程序执行过程中某个特定的点,比如某方法调用的时候或者处理异常的时候。在Spring AOP中,一个连接点总是表示一个方法的执行。

    通俗讲:

    层于层之间调用的过程中,目标层中可供调用的方法,就称之为连接点。

    b.切入点(Pointcut

    匹配连接点的断言。通知和一个切入点表达式关联,并在满足这个切入点的连接点上运行(例如,当执行某个特定名称的方法时)。切入点表达式如何和连接点匹配是AOP的核心:Spring缺省使用AspectJ切入点语法。

    通俗讲:

    在连接点的基础上 增加上切入规则 选择出需要进行增强的切入点 这些基于切入规则选出来的连接点 就称之为切入点。

    c.切面(Aspect

    一个关注点的模块化,这个关注点可能会横切多个对象。事务管理是J2EE应用中一个关于横切关注点的很好的例子。在Spring AOP中,切面可以使用基于模式)或者基于@Aspect注解的方式来实现。

    通俗讲:

    狭义上就是 当spring拦截下切入点后 讲这些切入点 交给 处理类 进行功能的增强,这个处理类就称之为切面。

    广义上来讲 讲 spring底层的代理 切入点 和 处理类 加在一起 实现的 对层与层之间调用过程进行增强的机制 称之为切面。

    d.通知(Advice

    在切面的某个特定的连接点上执行的动作。其中包括了“around”、“before”和“after”等不同类型的通知(通知的类型将在后面部分进行讨论)。许多AOP框架(包括Spring)都是以拦截器做通知模型,并维护一个以连接点为中心的拦截器链。

     通俗讲:

    在spring底层的代理拦截下切入点后,讲切入点交由切面类,切面类中就要有处理这些切入点的方法,这些方法就称之为通知(也叫增强 增强方法)。针对于切入点执行的过程,通知还分为不同的类型,分别关注切入点在执行过程中的不同的时机。

    e.目标对象(Target Object

    被一个或者多个切面所通知的对象。也被称做被通知(advised)对象。 既然Spring AOP是通过运行时代理实现的,这个对象永远是一个被代理(proxied)对象。

     通俗讲:

    就是真正希望被访问到的对象。spring底层的动态代理对他进行了代理,具体能不能真的访问到目标对象,或在目标对象真正执行之前和之后是否做一些额外的操作,取决于切面。

    2.Spring的AOP入门案例

    a.导入aop相关开发包

    b.创建一个切面类

    package cn.tedu.aop;
    
    import org.springframework.stereotype.Component;
    
    @Component
    public class FirstAspect {
        public void before(){
        }
    }

    c.定义通知(增强)

    package cn.tedu.aop;
    
    import org.springframework.stereotype.Component;
    
    @Component
    public class FirstAspect {
        public void before(){
            System.out.println("before...");
        }
    }

    d.定义一个连接点

    AOPTest.java
    package cn.tedu.test;
    
    import org.springframework.context.ApplicationContext;
    import org.springframework.context.support.ClassPathXmlApplicationContext;
    
    import cn.tedu.service.UserService;
    
    public class AOPTest {
      @Test
        public void test01(){
            ApplicationContext context = new ClassPathXmlApplicationContext("applicationContext.xml");
            UserService userService = (UserService) context.getBean("userService");
            userService.addUser(); // 一个连接点
        }
    }
    UserService.java
    package cn.tedu.service;
    
    public interface UserService {
        public void addUser();
        public void updateUser();
        public void deleteUser();
        public void query();
    }
    UserServiceImple.java
    package cn.tedu.service;
    
    import org.springframework.stereotype.Service;
    
    @Service("userService")
    public class UserServiceImple implements UserService {
    
        @Override
        public void addUser() {
            System.out.println("增加用户。。");
        }
    
        @Override
        public void updateUser() {
            System.out.println("修改用户。。");
        }
    
        @Override
        public void deleteUser() {
            System.out.println("删除用户。。");
        }
    
        @Override
        public void query() {
            System.out.println("查询用户。。");
        }
    }

    e.配置切入点

    在MyEclipse中导入aop的schema约束文件,以便于在配置文件中可以提示标签。

    在其中配置切入点:

        <aop:config>
            <!-- 配置切入点 -->
            <aop:pointcut expression="within(cn.tedu.service.UserServiceImple)" id="pc01"/>
        </aop:config>
    

    f.定义切面

        <aop:config>
            <!-- 配置切入点 -->
            <aop:pointcut expression="within(cn.tedu.service.UserServiceImple)" id="pc01"/>
            
            <!-- 配置切入面 -->
            <aop:aspect ref="firstAspect">
                <aop:before method="before" pointcut-ref="pc01"/>
            </aop:aspect>
            
        </aop:config>
    firstAspect:切面类
    before:切面中的方法
    pc01:该通知(增强)方法绑定的切入点

    g.执行方法,发现切面确实起作用

    before...
    增加用户。。

    3.切入点表达式

    a.within表达式

    (1)通过类名进行匹配

    通过类名进行匹配 粗粒度的切入点表达式

    within(包名.类名)

    则这个类中的所有的方法都会别表达式识别,成为切入点。

    expression="within(cn.tedu.service.UserServiceImple)"

    (2)用 * 号匹配符

    匹配指定包下所有的类,注意,只匹配当前包,不包括当前包的子孙包。

    此处的 * 代表切除该包下的所有类

    expression="within(cn.tedu.service.*)"

    (3)用 * . * 号匹配符

     匹配包

    此处第一个 * 代表一层子目录,第二个 * 代表这个子目录下的所有的类

    expression="within(cn.tedu.service.*.*)"

     (4)用 .. * 号匹配符

    匹配指定包下及其子孙包下的所有的类

    此处的 ..*代表匹配指定包下所有的类

    expression="within(cn.tedu.service..*)"

    b.execution()表达式

    语法:execution(返回值类型 包名.类名.方法名(参数类型,参数类型…))

    (1)切出指定包下指定类下指定名称指定参数指定返回值的方法

    (2)切出指定包下所有的类中的query方法

    要求无参,但返回值类型不限。

    (3)切出指定包及其子孙包下所有的类中的query方法

    要求无参,但返回值类型不限。

    (4)切出指定包及其子孙包下所有的类中的query方法

    要求参数为int java.langString类型,但返回值类型不限。

    (5)切出指定包及其子孙包下所有的类中的query方法

    参数数量及类型不限,返回值类型不限。

    (6)切出指定包及其子孙包下所有的类中的任意方法

    参数数量及类型不限,返回值类型不限。这种写法等价于within表达式的功能。

  • 相关阅读:
    服务器 空间
    android 手动打包
    sql server 2000 完全卸载 2
    apk 优化
    asp.net 画 数据图表
    java 运行 bat win linux
    vb 生成 批处理
    国内平台
    委托
    observer 观察者模式
  • 原文地址:https://www.cnblogs.com/chuijingjing/p/9800254.html
Copyright © 2020-2023  润新知