暂无图片
暂无图片
暂无图片
暂无图片
暂无图片

spring IOC与spring Bean

movingbrick 2021-04-02
454

1.Spring IOC

IOC是一个容器,spring中,他会认为一切java资源都是javaBean

目的:管理这些Bean和他们之间的关系,包括bean的创建,事件,行为等

概念:一种通过描述(在java中可以是注解或者xml)并通过第三方去产生获取特定对象的方式

实现IOC的方法:依赖注入

IOC的设计主要是基于BeanFactoryApplicationContext两个接口,

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才能使用。

都是直接配置到配置文件,然后注入。

上一篇:spring特征与模块+springMVC原理

下一篇:JVM运行时内存区域

文章转载自movingbrick,如果涉嫌侵权,请发送邮件至:contact@modb.pro进行举报,并提供相关证据,一经查实,墨天轮将立刻删除相关内容。

评论