Spring-AOP轻松掌握

AOP简介

aop作用及优势

作用: 在程序运行期间, 在不修改源码的情况下对方法功能进行增强

(白话): 动态的增强代码功能.

优势: 减少重复代码, 提高开发效率, 并且便于维护

(白话): 好用了

aop底层实现

AOP的低层是通过Spring提供的动态代理技术实现的。

Spring通过动态代理技术动态的生成代理对象, 代理方法执行时进行增强功能的介入, 去调用目标对象的方法, 完成功能增强。

基于JDK的动态代理 (如下)

image-20210705104952413

目标方法接口

public interface TargetInterface {
    public void save();
}

目标方法实现

public class Target implements TargetInterface {
    @Override
    public void save() {
        System.out.println("save running......");
    }
}

增强方法

public class Advice {

    public void before(){
        System.out.println("前置增强...");
    }

    public void afterReturning(){
        System.out.println("后置增强...");
    }
}

测试

public class ProxyTest {

    public static void main(String[] args) {
        //创建目标对象
        Target target = new Target();

        //创建增强对象
        Advice advice =new Advice();


        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 {
                        advice.before();
                        method.invoke(target, args);
                        advice.afterReturning();
                        return null;
                    }
                });

        proxy.save();
    }
}

基于cglib的动态代理

image-20210705105036800

目标方法

public class Target {
    public void save() {
        System.out.println("save running......");
    }
}

增强方法

public class Advice {

    public void before(){
        System.out.println("前置增强...");
    }

    public void afterReturning(){
        System.out.println("后置增强...");
    }
}

测试

public class ProxyTest {

    public static void main(String[] args) {
        //创建目标对象
        Target target = new Target();

        //创建增强对象
        Advice advice =new Advice();

        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 {
                advice.before();
                Object invoke = method.invoke(target, args);
                advice.afterReturning();
                return invoke;
            }
        });
        Target proxy = (Target) enhancer.create();

        proxy.save();
    }
}

xml方式实现aop

image-20210705105436454

①导入坐标

<!-- https://mvnrepository.com/artifact/org.springframework/spring-context -->
<dependency>
    <groupId>org.springframework</groupId>
    <artifactId>spring-context</artifactId>
    <version>5.3.8</version>
</dependency>
<dependency>
    <groupId>org.aspectj</groupId>
    <artifactId>aspectjweaver</artifactId>
    <version>1.8.4</version>
</dependency>
<!-- https://mvnrepository.com/artifact/junit/junit -->
<dependency>
    <groupId>org.springframework</groupId>
    <artifactId>spring-test</artifactId>
    <version>5.3.

②创建目标接口和目标类

目标接口

public interface TargetInterface {    public void save();}

目标实现类

public class Target implements TargetInterface {    @Override    public void save() {        System.out.println("save running......");    }}

③创建切面类(增强方法类)

public class MyAspect {    public void before(){        System.out.println("前置增强....");    }    public void afterReturning(){        System.out.println("后置增强...");    }}

④交给Spring管理

I. 创建applicationcontext.xml

‖. 把对象交给Spring管理

<!--目标对象-->
<bean id="target" class="link.zishu.aop.Target"/><!--切面对象--><bean id="myAspect" class="link.zishu.aop.MyAspect"/>

⑤配置文件中配置织入关系

<!--配置织入, 告诉spring框架,哪些方法(切点)需要进行哪些增强(前置,后置增强)-->
<aop:config>    
	<!--声明切面-->
	<aop:aspect ref="myAspect">        
		<!--切面= 切点 + 通知-->        
		<!--pointcut="execution(public void link.zishu.aop.Target.save())"/>-->        <aop:before method="before" pointcut="execution( * link.zishu.aop.Target.save())"/>        <aop:after-returning method="afterReturning" pointcut="execution(* link.zishu.aop.Target.save())"/>
	</aop:aspect>
</aop:config>

⑥测试

@RunWith(SpringJUnit4ClassRunner.class)@ContextConfiguration("classpath:applicationContext.xml")
public class AopTest {    
	@Autowired    
	private TargetInterface target;    
	@Test    
	public void Test1(){
		target.save();    
	}
}

注解方式实现aop

image-20210705110342083

①创建目标接口和目标类

目标接口

public interface TargetInterface {    public void save();}

目标实现类

public class Target implements TargetInterface {    @Override    public void save() {        System.out.println("save running......");    }}

②创建切面类(增强方法类)

public class MyAspect {    public void before(){        System.out.println("前置增强....");    }    public void afterReturning(){        System.out.println("后置增强...");    }}

③交给Spring管理

通过Component注解, 交给Spring管理

image-20210705110929314

④在切面类中使用注解配置织入关系

通过不同的注解, 配置不同增强。 例如: 前置增强 @Before 后置增强 @AfterReturning

@Before("execution(* link.zishu.anno.Target.save())")
public void before(){    
	System.out.println("前置增强....");
}

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

<!--开启注解扫描 -->
<context:component-scan base-package="link.zishu.anno"/>
<!--aop的自动代理-->
<aop:aspectj-autoproxy />

⑥测试

@RunWith(SpringJUnit4ClassRunner.class)@ContextConfiguration("classpath:applicationContext-anno.xml")
public class AnnoTest {    
	@Autowired    
	private TargetInterface target;    
	@Test    
	public void Test1(){        
		target.save();    
	}
}

增强分类

方法名方法名解释
前置通知@Before调用方法之前通知
后置通知@After-returning调用方法之后通知(方法执行成功时)
环绕通知@Around方法调用前后自定义的一些操作
异常通知@After-throwing调用方法之后通知(方法抛出异常时)
最终通知@After调用方法之后通知,不管方法执行状态
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值