从结果来看,为啥要学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