Spring
spring 核心容器:bean、core、contex(核心容器对象)、spEL
耦合可以理解为程序间的依赖关系 比如类的依赖 方法的依赖。耦合不能消除 只能降低,解耦就是降低依赖度。比如编译期的依赖 可以改为运行期的依赖 就是降低耦合度的一种方法,也叫解耦。反射可以实现编译期的依赖变成运行期的依赖。spring也是通过反射的方法实现一些程序间的解耦。通过读取配置文件获取一些在实际部署中才知道的变量的过程 ,也是解耦的一个思路。工厂模式 也可以进行解耦
bean:可重用组件也叫做bean。javabean在spring包括实体类 等各种可以重用的组件的统称,比如一个service或者dao就可以称为javabean
spring通过xml文件或者yml文件或者其他文件,即配置文件 以及工厂方法,运用反射的方式 动态创建javabean来实现代码的低耦合或者说解耦。
反射创建的对象 每次都调用默认构造函数,如果多线程场景下 ,会出现大量重复创建javabean的现象。这样的情况下,内存浪费,以及各种线程不安全、效率低下的问题就会出现。因此 spring引入了容器的概念 。容器专门用来存放javabean
IOC:控制反转,指类或方法将创建对象的权利交给框架或者工厂,包括依赖注入和依赖查找,降低了程序间的耦合度。
ApplicationContex采用立即加载的方式创建对象,也就是说 读取完配置文件就马上创建对象并放入核心容器当中。适合单例对象。
BeanFactory创建核心容器时,采用延迟加载的方式,也就是说当去获取对象时,才会去创建对象。适合多例对象的创建。这种方式已经被废弃。
spring对bean的管理方式(spring IOC)
1)创建对象的三种方式
1.使用默认构造函数创建,在spring的配置文件中使用bean标签,配以id和class属性,且没有其他标签和属性时(2和3就是反例)。采用的就是默认构造函数的方式创建,如果没有默认构造函数,则对象无法创建。
2.使用普通工厂中的方法创建对象,使用某个类的方法创建对象 并存入容器当中。
3.使用静态工厂或者其它类中的静态方法创建对象 并存入容器当中。
2)bean的作用域
3)bean的生命周期
spring的依赖注入
Dependency Injection降低程序间的耦合,依赖关系的管理都交给spring来维护
当前类需要使用到其他类的对象,由spring为我们提供,我们只需要在配置文件中说明依赖关系即可。这就是依赖注入
能注入的对象有基本类型 、String、其他bean类型、复杂类型/集合类型
注入方式有三种:
1.使用构造函数
2.使用set方法
3.使用注解提供
@Component:用于把当前对象存入spring容器当中,单例的;注解的value是bean的id,如果省略,该id默认是类名且首字母小写。基于注解的依赖注入,需要告诉框架需要扫描的注解所在的包,springboot基于注解的依赖注入,默认是从根目录下开始扫描 也就是主类所在的目录开始。
@Controller:用于表现层 不是强制
@Service:用于服务层 也不是强制的
@Repository:用于持久层 也不是强制的
以上三个注解是框架为我们提供的明确的三层注解,使得代码分层更明确一些,作用与Component一致
@Autowired:自动按照类型注入 只要容器中有唯一一个bean对象类型和需要注入的变量类型一致,就可以注入成功。出现位置:可以是成员变量 可以是方法。使用注解时 set方法就不是必须的了。Spring IOC容器是一个map结构。自动按照类型注入。自动按照类型注入。如果一个类型都不能匹配 则会报错。如果有多个类型匹配上,则查看注解的value(默认是注入的变量名称)是否与容器的bean id一致,一致则注入成功,不一致则报错.
@Qualifier:作用是按照类中注入的基础上再按照名称注入,它在给类成员注入时不能单独使用,需要与@Autowired配合使用,但在给方法注入时 可以单独使用。注解的value用于指定注入的bean 的 id。
@Resource:作用是直接按照bean 的id注入 , 属性是name。
以上三个注解只能注入其他bean类型的的数据,不能注入基本类型 以及基本类型的包装类。集合类型只能依赖xml文件注入。
@Value:用于注入基本类型和String类型的数据,它的属性是value,用于指定数据的值,它可以使用spring中的 spEL(spring中的el表达式)spEL表达式$(表达式)
@Scope:作用用于指定bean的作用域 ,与上文中所讲的作用域一致 ,默认是单例。
@Configration
@ComponentScan @ComponentScans
@bean
@Import
@PropertySource:用于注入配置文件中的bean
spring整合 junit
面向切面编程(AOP)
动态代理
什么是动态代理
字节码随用随创建,不修改方法的基础上 实现方法的增强
个人理解指将某一个或多个步骤从两端分离出来 交由其他部分来来处理,实现两端的解耦。
基于接口的动态代理
基于jdk提供的
基于子类的动态代理
基于cglib
AOP
什么是AOP
AOP 面向切面编程 指在程序运行过程中 不修改源码而实现代码增强的手段,通过预编译方式和运行动态代理实现程序功能的统一维护的一种手段。简单说 就是将重复代码抽取出来,在执行时候,使用动态代理的方法,进行方法增强。
Spring中的AOP
AOP相关术语
连接点:一般指方法
切入点:指对哪些方法进行拦截增强,即需要增强的连接点才是切入点
通知类型:前置通知 后置通知 异常通知 最终通知,这四个通知 又称为环绕通知
Spring中基于xml的AOP配置
Spring中基于注解的AOP配置
一般使用环绕通知 因为非环绕通知 会有顺序问题。
spring如何解决循环依赖问题
spring只支持处理单例对象创建时的循环依赖,不支持多例创建时的循环依赖。
当出现循环依赖时,首先需要去singletonObjects Map中查找对象,如果找不到,则从earlySingletonObjects Map中查找,如果还找不到,则从singletionFactories Map中去查找,如果找到,就将对象singletionFactories(初始缓存)中移除,并将对象放入earlySingletonObjects 中