Spring
[百度1](http://www.baidu.com/" 百度一下")
Spring解决的问题
- 之前代码耦合性太高,service层要使用dao,要添加相应的dao实现类作为成员变量,但有一天想换实现类,就需要修改源代码,不符合开闭原则
开闭原则:程序对于拓展是开放的,对修改关闭 - 控制事务繁琐,spring的AOP,面向切面编程,方便的对代码进行增强。是我们更关注业务逻辑代码,而不是无关的日志记录等操作
- 方便集成第三方框架,向上集成表现层,向下集成持久层
Spring 三大概念
- IoC
控制反转,把创建对象的权利交给spring去做,我们只需在使用到的时候去从spring容器中去取。spring通过读取配置中的元配置对bean对象进行创建
配置的三种方式
- 基于xml配置,古老,结构清晰,但bean对象过多配置会繁琐。但是有些不能使用注解配置的仍然需要使用xml的配置
- 基于注解,简单,但是不直观,较常用
- 基于java代码配置,在springboot中很常见,通常配合注解进行使用
- DI
依赖注入,通常DI概念应该包含在Ioc中,是指在创建对象的时候把对象依赖的对象给注入进去 - AOP
面向切面编程
Ioc和DI
Spring测试框架
传统junit测试是在每一次test去启动spring容器 ,不仅启动开销大,而且每次测试都是非正常关闭容器。
spring测试是在spring容器中去开启test,会自动关闭spring容器。传统测试 需要手动去调用容器的关闭操作
Spring 创建对象的四种方式
- 构造器创建(常用)
- 静态工厂创建,不推荐
- 实例工厂创建,不推荐
- 实现FactoryBean接口创建(后面框架会使用)
BeanFactory接口和ApplicationContext接口区别
- BeanFactory只支持Ioc相关操作,即创建,销毁和管理bean。同时它是在用到bean的时候才会去创建bean
- applicationContext继承自beanfactory接口,除了ioc相关操作,还包括Aop和国际化,事务等其他操作。它是在spring容器启动的时候就把所管理的bean进行创建
bean对象作用域问题
- singleton,单例,在spring容器中仅会存在一个bean实例。spring容器关闭,bean会被销毁
- prototype,多例,每次从容器中取出bean的时候都会创建出一个新的bean。容器关闭,但bean不被销毁,因为对象并不被spring容器所管理
bean对象的初始化和销毁(生命周期 )
bean标签中有init-method和destroy-method.前者在构造器执行后即对象创建后执行,后者会在容器关闭之前执行。注意如果如果bean的scope是prototype,spring容器只会去创建和初始化对象,这个对象并不会被容器管理,因此即便容器关闭也不会执行bean的销毁方法
DI注入常用方式(xml)
- 基于setter,使用标签,类中必须相应的属性(提供setter)
- 基于构造器,使用标签,类中必须有相应的构造器
xml中引入其他配置文件
区分以下两个
- 引入properties,下面的配置需要使用属性占位符去取值,比如数据库连接信息
<context:property-placeholder location="classpath:db.properties"/>
- 引入其他的spring配置的xml文件,比如后期会有个总的application-context文件,里面会引入其他的service层,dao层配置文件,方便进行管理
<import resource=""/>
补充:
Spring中有很多命名空间,比如context:和aop:等,背后都有相应的一个处理器去处理和解析这些命名空间,这些处理类都实现了一个接口NamespaceHandler,里面每个属性都会有个对应的parser,比如下边的ContextNamespaceHandler
@Override
public void init() {
registerBeanDefinitionParser("property-placeholder", new PropertyPlaceholderBeanDefinitionParser());
registerBeanDefinitionParser("property-override", new PropertyOverrideBeanDefinitionParser());
registerBeanDefinitionParser("annotation-config", new AnnotationConfigBeanDefinitionParser());
registerBeanDefinitionParser("component-scan", new ComponentScanBeanDefinitionParser());
registerBeanDefinitionParser("load-time-weaver", new LoadTimeWeaverBeanDefinitionParser());
registerBeanDefinitionParser("spring-configured", new SpringConfiguredBeanDefinitionParser());
registerBeanDefinitionParser("mbean-export", new MBeanExportBeanDefinitionParser());
registerBeanDefinitionParser("mbean-server", new MBeanServerBeanDefinitionParser());
}
基于注解的配置
- DI注解配置
在xml中添加context:annotation-config/可省略,但web环境必须添加
- 注入对象
方式一 @Autowired+@Qulifier
方式二 @Resource - 注入简单类型数据
@Value,通常很少为某个属性直接注入常量值,通常用于读取properties文件后,将文件中的key值注入进来,但要注意,解析文件一定要有<context:property-placeholder location=“classpath:db.properties”/> 配置,或者在javaconfig配置场景下,提供相应的读取解析类
-
Ioc注解配置
在xml中添加<context:component-scan base-package="