Spring AOP

AOP

  • 概念
    • AOP的动态代理技术
  • spring的AOP
    • 相关概念(词汇)
    • AOP开发的三步曲
  • XML的AOP开发
    • 切点表达式
    • 通知的类型
    • 切点表达式的抽取
    • 植入的配置
  • 注解的AOP配置
    • 开发的步骤

概念

  • Aspect Oriented Programming 面向切面编程
  • 预编译,运行期间,动态代理技术,解耦

AOP的动态代理技术

  • JDK代理:接口
  • cglib:父类

spring的AOP

  • 是对JDK代理和cglib代理的封装
  • jdk代理是原生的,速度快,但是需要接口的支持
  • cglib是第三方的,不需要接口

相关概念(词汇)

  • Target 目标对象,承载了连接点
  • Proxy 代理对象,承载了通知(增强方法)
  • joinpoint 可以被增强的方法
  • pointcut 被增强的方法
  • advice 通知/增强 ,增强方法的逻辑
  • aspect 切面 (切点+增强/通知)
  • weaving 织入 切点和通知结合的过程

AOP开发的三步曲

  • 目标方法 目标对象
  • 增强方法 代理对象
  • 配置结合
Spring 框架监控切入点方法的执行。一旦监控到切入点方法被运行,使用代理机制,动态创建目标对象的代理对象,根据通知类别,在代理对象的对应位置,将通知对应的功能织入,完成完整的代码逻辑运行。

XML的AOP开发

  • 导入AOP 坐标 context, aspectjweaver
  • 目标类和目标接口
  • 切面类(有增强方法)
  • 目标对象和切面对象放入spring容器中
  • appllicationContext.xml中配置织入关系
  • 测试

切点表达式

  • execution([修饰符] 返回值类型 包名.类名 .方法名(参数))
  • 修饰符可以省略
  • 返回值类型、包名、类名、方法名可以使用星号* 代表任意
  • 包名与类名之间两个点 … 表示当前包及其子包下的类
  • 参数列表可以使用两个点 … 表示任意个数,任意类型的参数列表

通知的类型

  • aop:before
  • aop:after-returning
  • aop:around
  • aop:throwing
  • aop:after

切点表达式的抽取

```java

 
  pointcut-ref="myPointcut"

@Pointcut("execution(* com.itheima.anno.*.*(..))")
    public void pointcut(){}

```

植入的配置


    
        
    

注解的AOP配置

开发的步骤

  • 创建目标类和目标接口

  • 创建切面类

  • 将目标和切面对象放入spring容器中

  • 注解配置植入关系

  • 配置文件中开启扫描和AOP的自动代理

  • 测试

  • 动态代理的实现过程

public interface TargetInterface {
    public void method();
}

public class Target implements TargetInterface {
    @Override
    public void method() {
        System.out.println("i`m target method ...");
    }
}

public class ProxyDemo {
    public static void main(String[] args) {
        final Target target = new Target();
        TargetInterface proxy = (TargetInterface)Proxy.newProxyInstance(target.getClass().getClassLoader(), target.getClass().getInterfaces(), new InvocationHandler() {
            @Override
            public Object invoke(Object proxy, Method method, Object[] args) throws Throwable {
                System.out.println("strar...");
                Object invoke = method.invoke(target, args);
                System.out.println("end...");
                return invoke;
            }
        });
        target.method();
        proxy.method();
    }
}
  • cglib的动态代理
  • enhancer增强器 setSuperclass()给其指定父类,参数是父类的class文件
  • Interceptor 拦截器
public class Proxy {
    public static void main(final String[] args) {
        final Target target = new Target();
        Enhancer enhancer = new Enhancer();
        enhancer.setSuperclass(Target.class);
        enhancer.setCallback(new MethodInterceptor() {
            @Override
            public Object intercept(Object o, Method method, Object[] objects, MethodProxy methodProxy) throws Throwable {
                System.out.println("start...");
                Object invoke = method.invoke(target, objects);
                System.out.println("end...");
                return invoke;
            }
        });
        Target proxy = (Target)enhancer.create();
        proxy.method();
    }
}
  • XML AOP流程
  • 导入AOP 坐标 context, aspectjweaver
  • 目标类和目标接口
  • 切面类(有增强方法)
  • 目标对象和切面对象放入spring容器中
  • appllicationContext.xml中配置织入关系,指定切面对象,指定前置方法和切点表达式
  • 测试 替换运行期,指定配置文件
public interface TargetInterface {
    public void method();
}

public class Target implements TargetInterface {
    @Override
    public void method() {
        System.out.println("i`m need enhancer...");
    }
}

public class MyAspect {
    public void before(){
        System.out.println("i will give you some magic...");
    }
}

@RunWith(SpringJUnit4ClassRunner.class)
@ContextConfiguration("classpath:applicationContext.xml")
public class TestSpring{
    @Autowired
    private TargetInterface target;

    @Test
    public void test1(){
        target.method();
    }
}
<bean id="target" class="com.itcast.ipm.Target">bean>
    <bean id="myAspect" class="com.itcast.MyAspect">bean>

    <aop:config>
        <aop:aspect ref="myAspect">
            <aop:before method="before" pointcut="execution(public void com.itcast.ipm.Target.method())">aop:before>
        aop:aspect>
    aop:config>
  • 环绕 ProceedingJoinPoint 正在执行的连接点,也可以理解位切点 proceed 开始,行进
public void around(ProceedingJoinPoint pjp) throws Throwable {
        System.out.println("one...");
        Object o = pjp.proceed();
        System.out.println("two");
    }
  • 注解开发AOP的流程
  • 创建目标类和目标接口 目标类要用注解的方法送入容器中component(“id”)
  • 创建切面类 放入容器,声明切面@Aspect,抽取切点表达式 @Pointcut(“execution(包.类.方法(参数))”)
  • 将目标和切面对象放入spring容器中
  • 注解配置植入关系 在增强方法上@增强位置
  • 配置文件中开启扫描和AOP的自动代理 component-scan, aspectj-autoproxy
  • 测试 替换运行期,指定配置,导入测试对象
public interface TargetInterface {
    public void method();
}

@Component("target")
public class Target implements TargetInterface {
    @Override
    public void method() {
        System.out.println("i`m need enhancer...");
    }
}

@Component("mysapect")
@Aspect
public class MyAspect {
//    @Before("mypointcut()")
    public void before(){
        System.out.println("i will give you some magic...");
    }

    @Pointcut("execution(* com.itcast.anno.imp.*.*())")
    public void mypointcut(){
    }

    @After("mypointcut()")
    public void after(){
        System.out.println("i`m the finally method");
    }
}

@RunWith(SpringJUnit4ClassRunner.class)
@ContextConfiguration("classpath:applicationContext01.xml")
public class AnnotationTest {
    @Autowired
    private TargetInterface target;
    @Test
    public void test1(){
        target.method();
    }
}
	<contextt:component-scan base-package="com.itcast.anno">contextt:component-scan>
	<aop:aspectj-autoproxy>aop:aspectj-autoproxy>

你可能感兴趣的:(java)