1.Spring IOC
IOC是一个容器,spring中,他会认为一切java资源都是javaBean
目的:管理这些Bean和他们之间的关系,包括bean的创建,事件,行为等
概念:一种通过描述(在java中可以是注解或者xml)并通过第三方去产生获取特定对象的方式
实现IOC的方法:依赖注入
IOC的设计主要是基于BeanFactory和ApplicationContext两个接口,
BeanFactory是最底层的接口,
ApplicationContext是BeanFactory的子接口,并且对BeanFactory功能做了很多有用的扩展。
BeanFactory中的方法
getBean方法 | 获取配置给springIOC的bean,可以是字符串,也可以是Class类型,由于Class类型可以扩展接口或者实现类,所以在一定程度上会存在使用父类无法准确获得实例的异常。因为容器无法判断具体的实现类。 |
isSingleton | 是否是单例,默认为true |
isPrototype | 原型模式,为真,表示每次从容器中获取bean,容器就生成新的实例。默认是false |
getAliases | 获取别名。 |
对有状态bean和无状态bean的理解
有状态会话bean singleton | 每个用户有自己特有的一个实例,在用户的生存期内,bean保持了用户的信息,即“有状态”;一旦用户灭亡(调用结束或实例结束),bean的生命期也告结束。即每个用户最初都会得到一个初始的bean。 |
无状态会话bean prototype | bean一旦实例化就被加进会话池中,各个用户都可以共用。即使用户已经消亡,bean 的生命期也不一定结束,它可能依然存在于会话池中,供其他用户调用。由于没有特定的用户,那么也就不能保持某一用户的状态,所以叫无状态bean。但无状态会话bean 并非没有状态,如果它有自己的属性(变量),那么这些变量就会受到所有调用它的用户的影响,这是在实际应用中必须注意的。 |
bean的整个生命周期负责:容器在初始化、配置、装饰或者是装配完一个prototype实例后,将它交给客户端,随后就对该prototype实例不闻不问了。不管何种作用域,容器都会调用所有对象的初始化生命周期回调方法。但对prototype而言,任何配置好的析构生命周期回调方法都将不会被调用。清除prototype作用域的对象并释放任何prototype bean所持有的昂贵资源,都是客户端代码的职责。(让Spring容器释放被prototype作用域bean占用资源的一种可行方式是,通过使用bean的后置处理器,该处理器持有要被清除的bean的引用。) |
Request | 一次request一个实例,请求结束就销毁 |
session | 一次Http session中,容器会返回该bean的同一个实例,请求结束就销毁 |
global | 在一个全局的http session中,容器会返回该bean的同一个实例,仅在使用portlet context时有效 |
IOC的初始化和依赖注入(初始化之后,才会进行依赖注入
IOC容器的初始化是通过refresh()方法来启动的(refresh()方法很好的使用了模板方法模式)
初始化3步
Resource定位 | IOC根据开发者的配置,进行资源定位,定位的内容是由开发者所提供的,也就是找到我们通常所说“applicationContetx.xml”等配置文件或者注解方式,将各种资源文件封装成相应的Resource类,这样我们可以通过Resource接口提供的操作,对资源进行统一的访问 |
BeanDefinition的载入 | 根据开发者的配置获取对应的pojo,用以生成对应实例的过程 |
BeanDefinition的注册 | 把之前载入的pojo往IOC容器中注册,这样就可以通过描述获得Bean了,这个过程通过调用BeanDefinitionregistry接口实现,实际上是放在了IOC容器内部的HashMap进行管理 |
Lazy-init,默认为false,表示IOC会自动初始化bean,为true时,那么当我们使用IOC容器的getBean方法获取它时,他才会初始化,完成依赖注入 |
2.spring bean
2.1 Spring Bean的5种作用域
1.singleton:单例模式(多线程不安全),无论多少个bean引用它,始终指向同一个对象,缺省默认配置为singleton。
<bean id = "UserDao" class = "com.ioc.UserDaoImpl"scope = "singleton"/>
2.propotyoe:原型模式,每次使用时都创建一个新的Bean实例,每个Bean
实例都有自己的属性和状态,根据经验,有状态的Bean使用prototype作用域,无状态的Bean使用singleton作用域。
3.Request:一次Request一个实例, 在一次HTTP请求种,容器会返回该Bean 的同一实例,不同的HTTP请求则产生不同的Bean,而且该Bean仅在当前HTTP Request内有效,当前请求结束,就被销毁。
4.session:在一次HTTP session种容器返回同一个实例,请求结束就销毁
5.global Session:在一个全局的HTTP Session种,该容器会返回该Bean的同一实例,仅在使用porlet context时有效。
2.2 Spring Bean的生命周期

2.3 spring依赖注入的四种方式
1.构造器注入,构造函数或者xml配置
2.setter方法注入,setXxx或者xml配置
3.静态工厂注入,通过调用静态工厂的方法来获取自己需要的对象,为了让spring管理所有的对象,我们不能直接通过"工程类.静态方法()"来获取对象,而是依然通过spring注入的形式获取。
//静态工厂
//静态工厂public class DaoFactory{public static final FactoryDao getStaticFactoryDaoImpl(){return new StaticFactoryDaoImpl();}}public class SpringAction{//注入对象private FactoryDao staticFactoryDao;//注入对象的set方法public void setStaticFactoryDao(FactoryDao staticFactiryDao){this.staticFactoryDao = staticFactoryDao;}}
//factory-method="getStaticFactoryDaoImpl"指定调用哪个工厂方法<bean name = "springAction" class="SpringAction">//使用静态工厂的方法注入对象<property name="staticFactoryDao" ref="staticFactoryDao"/></bean>//此处获取对象的方法是从工厂类中获取静态方法<bean name = "staticFactoryDao" class="DaoFactory" factory-method="getStaticFactoryDaoImpl"/>
4.实例工厂注入,获取对象实例的方法不是静态的,所以需要先new 工厂类,再调用普通的实例方法。
//实例工厂public class DaoFactory{public FactoryDao getFactoryDaoImpl(){return new FactoryDaoImpl();}}public class SpringAction{//注入对象private FactoryDao actoryDao;public void setFactoryDao(FactoryDao factiryDao){this.factoryDao = factoryDao;}}
2.4 装配Bean
1.XML中显示配置(优先级最低)
2.注解装配
1.组件扫描,通过定义资源的方式,让Spring IOC容器扫描对应的包,从而把Bean装配进来。@Component注解,搭配@ComponentScan使用
@ComponentScan默认扫描当前包的路径,可以定义多个包,多个类
2.自动装配,通过注解定义,使得一些依赖关系可以通过注解完成。
@Autowired注解。spring是先完成Bean的定义和生成,然后寻找要注入的资源,也就是当spring生成所有的Bean后,如果发现这个注解,他就会在Bean中查找到对应的类型,将其注入进来,这样就完成了依赖注入。默认情况下,找不到会抛出异常,可以通过@Autowired的配置项required = false配置其是可有可无的。
3.@Bean注解,四个配置项
name:字符串数组,允许配置多个BeanName。
autowire:标识是否是一个引用的Bean对象,默认是Autowire.No
initMethod::自定义初始化方法
destroyMethod:自定义销毁方法
4.使用Profile(很少看到),用@Profile注解,xml配置,但是需要手动激活Profile才能使用。
都是直接配置到配置文件,然后注入。




