天天看点

spring基本介绍一(ioc)

一,什么是spring

              spring是一款full-stack轻量级的开源框架,他是以Ioc和aop为核心。

     那么问题来了,什么是IOC呢?

                IOC称为控制反转,我们以前创建类的时候都是使用new的方式创建的,我们称为主动获取或者说控制正转,而我们的IOC控制反转呢,他就特殊了,是由我们的工厂创建放入容器 中,,当我们使用对象时,工厂就会提供给我们,是被动地接收的。

     那么我们来说一下什么是工厂呢?

                在这里所说的是工厂模式,工厂模式是我们最常用的实例化对象模式了,是用工厂方法代替 new 操作的一种模式。工厂模式在 Java 程序系统可以说是随处可见。因为工厂模式就相当于创建实例对象的 new,我们经常要根据类 Class 生成实例对象,工厂模式也是用来创建实例对象的,工厂模式在后期会给你系统带来更大的可扩展性和尽量少的修改量,提升可扩展性和可维护性。

     那么我们来说一下什么是AOP?

                面向切面编程。通过预编译方式和运行期动 态代理实现程序功能的统一维护的一种技术。简单来说,aop 是面向切面编程,是使用动态代理技术,实现在不修改 java 源代码的情 况下,运行时实现方法功能的增强。减少重复代码提高开发效率,统一管理调用,便于维护,

                AOP的实现原理:在spring 中,框架会根据目标类是否实现了接口来决定采用哪种代理的方式。如果目标对象实现接口,使用的就是jdk动态代理,如果目标对象没有实现接口那么就是使用cglib动态代理。

     问题又来了,什么是jdk动态代理,cglib动态代理又是什么呢?

               动态代理:

                      代理类在程序中运行时创建的代理方式被称为动态代理。

               jdk动态代理有以下几个特点:

                     代理对象,需要实现接口

                     代理对象的生成,是利用jdk的api,在内存中动态生成的对象

                      jdk代理类所在的包是:java.lang.reflect.Proxy,只需要使用newProxyInstance方法,不过有三个参数

static Object newProxyInstance(ClassLoader loader, Class<?>[]
              interfaces,InvocationHandler h )
           

                    注意该方法是在 Proxy 类中是静态方法,且接收的三个参数依次为:

                            ClassLoader loader,:

                            指定当前目标对象使用类加载器,获取加载器的方法是固定的

                            Class<?>[] interfaces,:

                            目标对象实现的接口的类型,使用泛型方式确认类型

                             InvocationHandler h:

                             事件处理,执行目标对象的方法时,会触发事件处理器的方法,会把当前执行目标对象的

                              方法作为参数传入。

             演示

// 对目标对象生成代理对象
 IStar proxy = (IStar)Proxy.newProxyInstance(
 //1. 类加载器
 App.class.getClassLoader(),
 //2. 目标对象实现的接口
 target.getClass().getInterfaces(),
 //3. 事件处理程序
 new InvocationHandler() {
 @Override
 public Object invoke(Object proxy, Method method, Object[]
args) throws Throwable {
 // 获取方法参数
 Double money = (Double) args[0];
 // 判断
 if (money > 100000){
 // 调用目标对象方法并返回
return method.invoke(target,args);
 } else {
 System.out.println("忙,没有档期!!!!");
 }
 return null;
 }
 }
 );
 // 生成的代理对象 class com.sun.proxy.$Proxy0 implements IStar
 // IStar proxy = (IStar)$Proxy0;
 // LiuDeHua proxy = (LiuDeHua)$Proxy0; // 报错:因为只能通过接口的引用接
收具体的实现。
 System.out.println(proxy.getClass());
 // 调用代理方法
 proxy.act(100001d);
 proxy.act(1d);
           

             Cglib代理   

                Cglib 代理,也叫作子类代理,它是在内存中动态构建一个子类对象从而实现对目标对 象功能的扩展. Cglib 是一个强大的高性能代码生成包,它可以在运行期扩展 java 类与实现 java 接 口.它广泛的被许多 AOP 的框架使用,例如 Spring AOP 和 synaop,为他们提供方法的 interception(拦截)

          cglib的使用

spring基本介绍一(ioc)
// 对目标对象创建代理对象, 使用 cglib 代理
 LiuDeHuaStar proxy = (LiuDeHuaStar)Enhancer.create(
 LiuDeHuaStar.class,
 new MethodInterceptor() {
 @Override
 public Object intercept(Object proxy, Method method,
Object[] args, MethodProxy methodProxy) throws Throwable {
 // 获取方法名称
 String methodName = method.getName();
 // 获取方法参数
 double money = (double) args[0];
 // 方法返回值
 Object reValue = null;
 // 判断
 if ("singing".equals(methodName)){
 // 判断
if (money > 100000) {
 // 调用唱歌方法
reValue = method.invoke(liudehua,args);
 }else{
 System.out.println("忙,没空开演唱会!");
 }
 }
 else if ("act".equals(methodName)) {
 if (money > 1000000) {
 // 调用目标对象
reValue = method.invoke(liudehua,args);
 } else {
 System.out.println("忙,不接新戏!");
 }
 }
 return reValue;
 }
 });
 System.out.println(proxy.getClass());
 // 调用代理方法
 proxy.singing(1);
 proxy.act(2000000);
           

代理的类不能为 final,否则报错 目标对象的方法如果为 final/static,那么就不会被拦截,即不会执行目标对象额外 的业务方法.

           AOP的专业术语

Pointcut(切入点): 所谓切入点是指我们要对哪些 Joinpoint 进行拦截的定义。

Advice(通知/增强): 所谓通知是指拦截到 Joinpoint 之后所要做的事情就是通知。 通知的类型: 前置通知,后置通知,异常通知,最终通知,环绕通知

Target(目标对象): 被代理的对象。比如动态代理案例中的演员。

Weaving(织入): 织入指的是把增强用于目标对象,创建代理对象的过程。spring 采用动态代理织入,AspectJ 采用编译 期织入和类装载期织入。

Proxy(代理): 一个类被 AOP 织入增强后,即产生一个结果代理类。比如动态代理案例中的经纪人。

Aspect(切面): 切面指的是切入点和通知的结合。

继续阅读