Spring框架是一个开放源代码的J2EE应用程序框架,IOC(控制反转)和AOP (面向切面编程)为内核,通俗讲Spring就是一个容器,用来存放 同类内容的集合 就叫做容器,在 Spring 构成应用程序主干并由Spring IoC容器管理的对象称为bean。bean是一个由Spring IoC容器实例化、组装和管理的对象,便于程序的解耦、开发方式的简化、支持AOP编程、支持声明式事务、程度测试简化、可集成多种优秀框架、大大降低JAVAEE API的的调用难度等优点
spring有哪些优势
1,方便解耦,简便开发
通过springd的IOC容器,可以将对象间的依赖关系交由spring容器去管理,避免编程造成的过度耦合
2,AOP编程支持
可以通过spring的AOP功能,方便进行面向切面编程,许多传统的OOP实现功能可以通过AOP去实现
3,声明式事务支持
可以将烦闷的单调的事务管理从代码中解脱出来,通过声明的方式进行灵活的进行管理
4,方便程序测试
可以用非容器的依赖关系进行几乎所有的测试
5,降低JavaEE的使用难度
对JavaEE的api进行了封装,使这些api的难度大大
6,方便集成各种优秀的框架
spring支持各种优秀框架(Sturts,Hibenate,Hessian,Quartz)等
Spring七大核心模块
1,核心容器(Spring Core)
2,应用上下文(Spring Context)
3,面向切面编程(Spring Aop)
4,Spring的Dao模块(Spring dao)
5,web模块(Spring web)
6,MVC模块(Spring Mvc)
8,对象实体映射(Spring ORM)
IOC(控制反转,DI依赖注入)
简单来说Spring框架会将把对象的控制权交给Spring容器去管理,依赖注入就是讲创建的Bean对象,而只要在配置文件需要描述它如何被创建之后一个IOC容器负责把它们组装装配起来
AOP(面向切面编程)
利用AOP可以对业务逻辑的各个部分进行隔离,从而使得业务逻辑各部分之间的耦合度降低,提高程序的可重用性,同时提高了开发的效率。
为什么要使用AOP(面向切面编程)
面向切面编程,通过预编译方式和运行期间动态代理实现程序功能的统一维护的一种技术,我们可以利用AOP的思想来对业务逻辑的各个部分进行隔离,从而使得业务逻辑各部分的耦合度降低,提高程序的可重用性,同时提高了开发的效率
AOP(面向切面编程)底层基本概念
Aspect(切面):
切面是切点和通知的组合称谓,就是变相给组合起了个名字。
连接点(join point):
连接点可以说是切点的全集。切点是连接点的子集。也可以理解为,连接点是我们没有定义那个select开头规则时,满足条件的全部的方法。 类里面哪些方法可以被增强,这些方法称为连接点
织入(weaving):
就是我们编写的希望Aop时执行的那个方法。我们通过Aop希望我们编写的方法在目标方法执行前执行,或者执行后执行,织入是一个过程,是将切面应用到目标对象从而创建出AOP代理对象的过程,织入可以在编译期、类装载期、运行期进行。
切点(pointcut ):
切点就是我们我们配置的满足我们条件的目标方法。比如我们规定:名字前面是select开头的才执行我们自定义的通知方法。那么这些select开头的方法就是切点, 实际被增强的方法是切入点
通知(也可称为增强)(advice ):
实际增强的逻辑部分称为通知,就是我们编写的希望Aop时执行的那个方法。我们通过Aop希望我们编写的方法在目标方法执行前执行,或者执行后执行
通知有多种类型:前置通知、后置通知、环绕通知、异常通知、最终通知
原理:必须是面向接口的,只有实现了具体接口的类才能生成代理对象
public class ProxyFactory {
//声明被代理的对象
private Object target;
//实现被代理的对象
public ProxyFactory(Object target) {
this.target = target;
}
//获取被代理的对象
public Object getProxy(){
//jdk中提供一个代理类Froxy,我们可以通过该类,获取代理的对象
//newProxyInstance(ClassLoader loader,Class>[] interfaces,InvocationHandler h)
//ClassLoader loader--被代理对象需要的类加载器
ClassLoader loader=target.getClass().getClassLoader();
//Class>[] interfaces--被代理对象实现的接口
Class>[] interfaces=target.getClass().getInterfaces();
// InvocationHandler h--被代理对象的方法值
InvocationHandler h=new InvocationHandler() {
@Override
public Object invoke(Object proxy, Method method, Object[] args) throws Throwable {
//method.getName()获取方法名
//Arrays.asList(args) 参数
System.out.println("before "+method.getName()+" method begin with"+ Arrays.asList(args));
//method:代理对象要代理的方法--指得测试类中的add方法
//invoke:回调该方法执行--指的是target
//ages:方法需要的参数
Object result = method.invoke(target, args);
return result;
}
};
Object o = Proxy.newProxyInstance(loader, interfaces, h);
return o;
}
}
原理:对于没有实现了接口的类,也可以产生代理,产生这个类的子类的方式
引入相关依赖
repMaven.cglib
cglib
3.2.5
创建一个工厂类并实现接口
public class ProxyFactory implements MethodInterceptor {
//声明被代理的对象
private Object target;
public ProxyFactory(Object target) {
this.target = target;
}
//实现被代理的对象
public Object gettarget(){
Enhancer enhancer=new Enhancer();
//1.指定代理对象的父类
enhancer.setSuperclass(target.getClass());
//2.指定该类的回调类
enhancer.setCallback(this);
//3.创建代理对象
return enhancer.create();
}
//执行代理方法是,触发的方法
public Object intercept(Object obj, Method method, Object[] args, MethodProxy proxy) throws Throwable {
System.out.println("=============");
Object invoke = method.invoke(target, args);
return invoke;
}
}
1,JDK动态代理实现了被代理对象的接口,CGLib动态代理继承了被代理对象
2,Cglib是针对类实现代理,主要是对指定的类生成一个子类,覆盖其中的方法
3,JDK和Cglib都是在运行期生成字节码,JDK是直接写Class字节码,Cglib使用ASM框架写Class字节码,Cglib代理实现更复杂,生成代理类比JDK效率低。
4,JDK调用代理方法,是通过反射机制调用,Cglib是通过FastClass机制直接调用方法,Cglib执行效率更高
5,CGLib动态代理是通过字节码底层继承要代理类来实现(如果被代理类被final关键字所修饰,那么抱歉会失败)。
6,在 JDK6 和 JDK7 版本时,JDK 动态代理的速度要比 CGLIB 动态代理慢,从 JDK8 开始,JDK 动态代理的速度要比 CGLIB 动态代理快
当Bean实现接口时,Spring就会用JDK的动态代理。
当Bean没有实现接口时,Spring使用CGlib是实现,可以强制使用CGlib(在spring配置中加入
总结:所谓的代理模式分为静态代理和动态代理
静态代理
静态代理中,我们对目标对象的每个方法的增强都是手动完成的,非常不灵活(比如接口一旦新增加方法,目标对象和代理对象都要进行修改)且麻烦(需要对每个目标类都单独写一个代理类)
大白话理解:举个例子人到了试婚年龄,父母总是迫不及待的开始到处为自己的子女相亲。这个父母替你相亲的过程就算所谓的代理
动态代理
相比于静态代理来说,动态代理更加灵活。我们不需要针对每个目标类都单独创建一个代理类,并且也不需要我们必须实现接口,可以通过动态代理类我们可以完成全部的代理功能
大白话理解 :随着自己时间和年两的增长,父母给儿子相亲的找个单一的代理介绍相亲已经满足不了你现在需求了,那么相亲这一业务发展成了一个产业,随之而来的出现了媒婆、婚介所等这样的形式可以不同样式动态的去满足的相亲的需求
前面我们提到AOP主要应用一些非核心业务逻辑中,我们看看AOP常见的应用场景
监控,日志,缓存,事务异常处理,持久化