Spring之二_AOP

本文探讨了Spring的AOP概念,包括连接点、切入点、通知和织入等,强调了AOP在不修改源码情况下对方法进行增强的优势。详细介绍了基于接口的JDK动态代理和基于子类的CGLIB动态代理的实现,以及它们在事务管理和全站中文乱码处理等场景中的应用。此外,还讨论了Spring中AOP的XML和注解配置方式,并提醒注意基于注解AOP的执行顺序问题。
摘要由CSDN通过智能技术生成

从结果来看,为啥要学AOP?
因为,框架中常出现只定义接口,然后就能调用方法的现象,也就是动态代理。这属于AOP的内容,不明白AOP就会一直搞不明白,“为啥明明是接口却可以调用方法”。
从教程来看,在涉及复杂的数据库操作时,也即使用事务时,动态代理的需求显现的更加明显。

===================
理一下IOC
1.配置文件用于为程序变量赋值很方便,如:为基本类型变量赋值
2.既然用配置文件赋值这么方便,那配置文件除了为基本数据类型赋值,能不能为对象赋值呢?

===============================
动态代理
特点:字节码随用随创建,随用随加载;(与装饰者模式区别,装饰者模式必须先创建一个类)
作用:不修改源码的基础上对方法增强
分类:
基于接口的动态代理
基于子类的动态代理

基于接口的动态代理:
涉及的类:Proxy
提供者:JDK官方
如何创建代理对象:
使用Proxy类中的newProxyIstance方法
创建代理对象的要求:
被代理类最少实现一个接口,如果没有则不能使用
newProxyInstance方法的参数:
ClassLoader:类加载器,用于加载被代理对象字节码,与被代理对象使用相同的类加载器【固定写法】
Class[]:字节码数组
用于使代理对象和被代理对象有相同的方法,有相同的接口就能有相同的方法【固定写法】
InvocationHandler:用于提供增强的代码,即实现如何代理;写一个该接口的实现类,通常是匿名内部类,但不是必须的;此接口的实现类都是谁用谁写。

proxy:代理对象的引用;
method:当前执行的方法;
args:当前执行方法所需的参数;
返回值:和被代理对象有相同的返回值;

// 对生产厂家进行要求的接口
public interface IProducer{
   
    public void saleProduct(float money);

    public void afterService(float money);
}

// 生产厂家类
public  class Producer{
   
    public void saleProduct(float money){
   
        System.out.println("销售产品,拿到钱" + money);
    }

    public void afterService(float money){
   
        System.out.println("售后服务,拿到钱" + money);
    }
}

// 客户类
// 不使用动态代理
public class client{
   
    public static void main(String[] args) {
   
    	// 找到一个生产厂家
        Producer producer = new Producer();
        // 给生产厂家钱,生产厂家给货
        producer.saleProduct(1000f);
    }
}

// 使用动态代理
// 达到的效果:不在方法所属的类中修改方法源码,而是在调用方法时才进行处理,实现方法的增强。
public class client{
   
    public static void main(String[] args) {
   
        final Producer producer = new Producer();

        IProducer proxyProducer = (IProducer) Proxy.newProxyInstance(
                producer.getClass().getClassLoader(),
                producer.getClass().getInterfaces(),
                new InvocationHandler() {
   
                    public Object invoke(Object proxy, Method method, Object[] args) throws Throwable {
   
                    	// 直接返回则就是原来的方法
                        // return method.invoke(producer,args);

                        Object returnValue = null;
                        // 1. 获取方法执行的参数
                        Float money = (Float) args[0];
                        // 2. 判断当前方法是不是要代理的方法,增强方法
                        if("saleProduct".equals(method.getName())){
   
                            returnValue = method.invoke(producer,money*0.8);
                        }
                        return returnValue;
                    }
                }
        );
        
        proxyProducer.saleProduct(1000f);
    }
}

局限性:被增强的方法必须是实现的某个接口的方法,如果被代理对象中该方法不是实现自某个接口,而是类中定义的一个普通方法,那该方法不能通过上述方式进行动态代理。

基于子类的动态代理:
涉及的类:Enhancer
提供者:第三方cglib库,需要引入依赖
如何创建代理对象:
使用Enhancer类中的create方法
创建代理对象的要求:
被代理类不能是最终类【因为最终类不能再创建子类】
create方法的参数:
Class:字节码,用于指定被代理对象的字节码;【通过字节码可以再获取类加载器等】
Callback:用于提供增强的代码,即实现如何代理;写一个该接口的实现类,通常是匿名内部类,但不是必须的;一般写的是Callback接口的子接口MethodInterceptor的实现类。

proxy:代理对象的引用;
method:当前执行的方法;
args:当前执行方法所需的参数;
methodProxy:当前执行方法的代理对象,用不上。
返回值:和被代理对象有相同的返回值;

<dependency>
	<groupId>cglib</groupId>
	<artifactId>cglib</artifactId>
	<version>2.1_3</version>
</dependency>

// 对生产厂家进行要求的接口
// 对生产厂家进行要求的接口
public interface 
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值