1 介绍
Spring框架是一个开放源代码的J2EE应用程序框架,是针对bean的生命周期进行管理的轻量级容器,有两大核心IOC(控制反转)和AOP(面向切面编程)。
2 IOC
1.1 IOC介绍
1、意思控制反转,对象创建的历由Spring框架完成,由容器管理对象的生命周期,需要的时候进行依赖注入(DI)即可
2、Spring的配置文件中配置了类的字节码位置及信息,容器生成的时候加载文件识别字节码信息,通过反射创建类的对象
1.2 IOC的使用
Spring创建对象的步骤
(1)定义spring的配置文件地址
(2)spring容器启动时加载指定的配置文件
(3)当spring扫描到bean标签时,加载属性id和class
(4)根据反射机制 根据class的路径反射,实例化对象
(5)Spring在内部维护了一个大型Map(k,v)集合(容器),bean中的id充当Map中的key,实例化对象充当中的value,形式:Map<id,实例化对象>,到此为止,spring容器启动成功
(6)从spring容器中通过id或者class类型获取对象
(7)根据对象调动业务
IOC的注入方式:
构造器注入,setter方法注入,根据注解注入
3 注解
(1)包扫描:
@ComponentScan:根据指定的包路径扫描注解,扫描当前包以及子孙包
(2)将类标识为配置类:
@Configuration:标识当前类为配置类
(3)对象创建,将对象交给spring容器管理
@Component @Controller @Service
@Repository:一般在dao层使用
@Bean:对象的key为方法的名字,需要配合@Configuration使用
(4)声明周期控制的注解
@Scope:控制多利和单例
@Lazy:懒加载
@PostConstruct:初始化方法
@PreDestory:销毁方法
Spring Bean的作用域
● 可以通过@Scope注解修改作用域
--当通过@Bean方法创建对象时,在方法的声明之前添加@Scope注解
– 当通过组件扫描创建对象时,在组件类的声明之前添加@Scope注解
@Configuration
public class SpringBeanFactory {
@Scope(“prototype”)
@Bean
public Random random() {
return new Random();
}
}
@Scope(“prototype”)
@Repository
public class UserMapper {
}
DI(Dependency Injection:依赖注入)
概念
是Spring框架实现IOC的核心实现,当某个类中声明了另一个类的属性(例如UserController类中声明了UserMapper类型的属性),则称之为依赖,Spring框架会帮你完成依赖项的赋值,称之为注入。
IOC与DI关系
Spring通过DI实现了IOC,IOC是目标,DI是实现此目标的重要手段
注入方式
(1)set方式注入 (2)构造方法注入 (3)工厂模式注入
具体实现
1、对象注入:用自动装配@Autowired或者@Autowired+@Qualifier(“名字”)
AOP(面向切面编程)
概念:
作为面向对象的一种补充,用于将那些与业务无关,但却对多个对象产生影响的公共行为和逻辑,抽取并封装为一个可重用的模块,这个模块命名为“切面”,springAOP使用的动态代理,所谓的动态代理就是说AOP框架不会去修改字节码,而是每次运行时在内存中临时为方法生成一个AOP对象,这个AOP对象包括了目标对象的全部方法,并且在特定的切点做了增强处理,并回调原对象的方法
Spring框架中用到了哪些设计模式
1、工厂模式:BeanFactory就是简单工厂模式的体现,用来创建对象的实例
2、单例模式:Bean默认为单例模式
3、代理模式:Spring的AOP功能用到了JDK的动态代理和CGLIB字节码生成技术
4、模板方法:用来解决代码重复问题。比如。RestTemplate,JmsTemplate,JapeTemplate
5、观察者模式:定义对象键一种一对多的依赖关系,当一个对象的状态发生变化时,所有依赖于它的对象都会得到通知被制动更新,如Spring和listener的实现--ApplicationListener
Spring事物的实现方式和实现原理
Spring事物的本质其实就是数据库对事物的支持,没有数据库的事务支持,spring是无法提供事物功能的,真正的数据库层的事物提交和回滚是通过binlog或者redo log实现的
spring事物实现主要有两种方法
1、编程式,beginTransaction(),commit(),rollback()等事物管理相关的方法
2、声明式,利用注解Transaction或者aop配置
单例bean的线程安全问题
1.单例bean对象对应的类存在可变的成员变量,并且其中存在改变这个变量的线程时,多线程操作该bean对象时会出现线程安全问题。
原因:多线程操作如果改变成员变量,其他线程无法访问该bean对象,造成数据混乱。
解决方法:1.在bean对象中避免定义可变成员变量;
2.在bean对象中定义一个ThreanLocal成员变量,将需要的可变成员变量保存在 TreadLocal中
ThreadLocal:叫做线程变量,意思是ThreadLocal中填充的变量属于当前线程,该变量对其他线程而言是隔离的,也就是说该变量是当前线程独有的变量。ThreadLocal为变量在每个线程中都创建了一个副本,那么每个线程可以访问自己内部的副本变量。
@Resource 和@Autowired 依赖注入的区别是什么?
@Resource:只能放在属性上,表示先按照属性名匹配IOC容器中对象id给属性注入值,若没有 成功,会继续根据当前属性的类型,匹配IOC容器中同类型对象来注入值。
@Autowird:放在属性上,表示先按照类型给属性注入值,如果IOC容器中存在多个与属性同类 型的对象,则会按照属性名注入值
也可以配合@Qualifier("IOC 容器中对象 id")注解直接按照名称注入值。