配色: 字号:
第2章 Spring中的Bean
2021-05-25 | 阅:  转:  |  分享 
  
学习目标掌握ApplicationContext容器使用属性setter方法注入的实现了解Bean的常用属性及其子元素熟悉Bean的作用域和
生命周期2.1Bean的配置2.1Bean的配置什么是Spring中的Bean?如果把Spring看做一个大型工厂,则Spr
ing容器中的Bean就是该工厂的产品。要想使用这个工厂生产和管理Bean,就需要在配置文件中告诉它需要哪些Bean,以及需要使用
何种方式将这些Bean装配到一起。Bean的本质就是Java中的类,而Spring中的Bean其实就是对实体类的引用,来生产Jav
a类对象,从而实现生产和管理Bean。Spring容器支持两种格式的配置文件:Properties文件和XML文件在实际开发中,
最常使用的是XML文件格式的配置方式,这种配置方式是通过XML文件来注册并管理Bean之间的依赖关系。XML配置文件的根元素是eans>,中包含了多个子元素,每一个子元素定义了一个Bean,并描述了该Bean如何被装配
到Spring容器中。关于元素的常用属性如下表所示:在配置文件中,通常一个普通的Bean只需要定义id(或name)
和class两个属性即可,定义Bean的方式如下所示:>:xsi="http://www.w3.org/2001/XMLSchema-instance"xsi:schemaLocatio
n="http://www.springframework.org/schema/beanshttp://www.springf
ramework.org/schema/beans/spring-beans.xsd">ass="com.unknown.Bean1"/>.Bean2"/>
如果在Bean中未指定id和name,则Spring会将class值当作id使用。2.2
Bean的实例化Bean的实例化有哪些方式?在面向对象的程序中,想要使用某个对象,就需要先实例化这个对象。同样,在Spring中,
要想使用容器中的Bean,也需要实例化Bean。实例化Bean有三种方式,分别为构造器实例化、静态工厂方式实例化和实例工厂方式实例
化(其中最常用的是构造器实例化)。2.2.1构造器实例化构造器实例化是指Spring容器通过Bean对应的类中默认的构造函数来实
例化Bean。接下来演示构造器实例化的使用:在上个项目中创建一个类packagecom.unknown.ioc;publicc
lassBean1{}配置xml文件xmlns="http://www.springframework.org/schema/beans"xmlns:xsi="ht
tp://www.w3.org/2001/XMLSchema-instance"xsi:schemaLocation="http
://www.springframework.org/schema/beanshttp://www.springframewor
k.org/schema/beans/spring-beans.xsd">om.unknown.ioc.UserDaoImpl"/>unknown.ioc.UserServiceImpl">ao"/>
<
/beans>创建实例importcom.unknown.ioc.Bean1;importorg.springframewor
k.context.ApplicationContext;importorg.springframework.context.s
upport.ClassPathXmlApplicationContext;publicclassInstanceTest1
{publicstaticvoidmain(String[]args){ApplicationContextapp
licationContext=newClassPathXmlApplicationContext("application
Context.xml");Bean1bean=(Bean1)applicationContext.getBean("b
ean1");System.out.println(bean);}}2.2.2静态工厂方式实例化静态工厂是实例化Bean的
另一种方式。该方式要求自己创建一个静态工厂的方法来创建Bean的实例。接下来演示静态工厂实例化的使用:在上个项目中创建一个类pac
kagecom.unknown.ioc;publicclassBean2{}创建一个Java工厂类,在类中使用静态方法获取
Bean2实例;packagecom.unknown.ioc;publicclassMyBean2Factory{pub
licstaticBean2createBean(){returnnewBean2();}}配置工厂类Beanmlversion="1.0"encoding="UTF-8"?>gframework.org/schema/beans"xmlns:xsi="http://www.w3.org/2001/XM
LSchema-instance"xsi:schemaLocation="http://www.springframework.
org/schema/beanshttp://www.springframework.org/schema/beans/spri
ng-beans.xsd">mpl"/>mpl">
bean1"class="com.unknown.ioc.Bean1"/>om.unknown.ioc.MyBean2Factory"factory-method="createBean"/>ns>创建实例importorg.springframework.context.ApplicationContext;impo
rtorg.springframework.context.support.ClassPathXmlApplicationCon
text;publicclassInstanceTest2{publicstaticvoidmain(String[
]args){ApplicationContextapplicationContext=newClassPathXm
lApplicationContext("applicationContext.xml");System.out.println
(applicationContext.getBean("bean2"));}}2.2.3实例工厂方式实例化实例工厂是采用直接
创建Bean实例的方式,在配置文件中,通过factory-bean属性配置一个实例工厂,然后使用factory-method属性确
定使用工厂中的哪个方法。接下来演示实例工厂实例化的使用:在上个项目中创建一个类publicclassBean3{}创建一个J
ava工厂类packagecom.unknown.ioc;publicclassMyBean3Factory{publi
cBean3createBean(){returnnewBean3();}}配置文件0"encoding="UTF-8"?>/schema/beans"xmlns:xsi="http://www.w3.org/2001/XMLSchema-instan
ce"xsi:schemaLocation="http://www.springframework.org/schema/bea
nshttp://www.springframework.org/schema/beans/spring-beans.xsd">
d="userService"class="com.unknown.ioc.UserServiceImpl">yname="userDao"ref="userDao"/>com.unknown.ioc.Bean1"/>MyBean2Factory"factory-method="createBean"/>ctory"class="com.unknown.ioc.MyBean3Factory"/>factory-bean="myBean3Factory"factory-method="createBean"/>ans>创建实例importorg.springframework.context.ApplicationContext;imp
ortorg.springframework.context.support.ClassPathXmlApplicationCo
ntext;publicclassInstanceTest3{publicstaticvoidmain(String
[]args){ApplicationContextapplicationContext=newClassPathX
mlApplicationContext("applicationContext.xml");System.out.printl
n(applicationContext.getBean("bean3"));}}2.3Bean的作用域2.3.1作用域的
种类Spring4.3中为Bean的实例定义了7种作用域,如下表所示:在上表7种作用域中,singleton和prototype
是最常用的两种作用域。2.3.2singleton作用域(默认)singleton是Spring容器默认的作用域,当Bean的作
用域为singleton时,Spring容器就只会存在一个共享的Bean实例。singleton作用域对于无会话状态的Bean(如
Dao组件、Service组件)来说,是最理想的选择。在Spring配置文件中,可以使用元素的scope属性,将Be
an的作用域定义成singleton。scope="singleton"/>2.3.3prototype作用域对需要保持会话状态的Bean(如Struts2的Ac
tion类)应该使用prototype作用域。在使用prototype作用域时,Spring容器会为每个对该Bean的请求都创建一
个新的实例。在Spring配置文件中,同样使用元素的scope属性,将Bean的作用域定义成prototype。eanid="bean1"class="com.unknown.ioc.Bean1"scope="prototype"/>2
.4Bean的生命周期了解Spring中Bean的生命周期的意义就在于,可以利用Bean在其存活期间的特定时刻完成一些相关操作
。这种时刻可能有很多,但一般情况下,常会在Bean的postinitiation(初始化后)和predestruction(销毁前
)执行一些相关操作。Spring容器可以管理Bean部分作用域的生命周期。有关说明具体如下:singleton作用域:Spring
容器可以管理singleton作用域的Bean的生命周期,在此作用域下,Spring能够精确的知道该Bean何时被创建,何时初始化
完成,以及何时被销毁。prototype作用域:prototype作用域的Bean,Spring只负责创建,当容器创建了Bean实
例后,Bean的实例就交给客户端代码来管理,Spring容器将不再跟踪其生命周期。Spring容器中Bean的生命周期流程如下图所
示:2.5Bean的装配方式Bean的装配可以理解为依赖关系注入,Bean的装配方式即Bean依赖注入的方式。Spring容器
支持多种形式的Bean的装配方式,如基于XML的装配、基于注解(Annotation)的装配和自动装配(其中最常用的是基于注解的装
配),本节将主要讲解这三种装配方式的使用。2.5.1基于XML的装配创建Java类,提供有参、无参构造以及属性setter方法;
packagecom.unknown.ioc;importjava.util.List;publicclassUser{
privateStringusername;privateIntegerpassword;publicString
getUsername(){returnusername;}publicvoidsetUsername(Strin
gusername){this.username=username;}publicIntegergetPassw
ord(){returnpassword;}publicvoidsetPassword(Integerpasswo
rd){this.password=password;}publicListgetList(){
returnlist;}publicvoidsetList(Listlist){this.lis
t=list;}privateListlist;publicUser(Stringusernam
e,Integerpassword,Listlist){super();this.username
=username;this.password=password;this.list=list;}public
User(){super();}}配置xml;<
beansxmlns="http://www.springframework.org/schema/beans"xmlns:x
si="http://www.w3.org/2001/XMLSchema-instance"xsi:schemaLocation
="http://www.springframework.org/schema/beanshttp://www.springfr
amework.org/schema/beans/spring-beans.xsd">ass="com.unknown.ioc.UserDaoImpl"/>"com.unknown.ioc.UserServiceImpl">userDao"/>
scope="singleton"/>an2Factory"factory-method="createBean"/>y"class="com.unknown.ioc.MyBean3Factory"/>ory-bean="myBean3Factory"factory-method="createBean"/>
"1"value="123456"/>"c
onstructorvalue1"
"constructorvalue2"st>
d="user2"class="com.unknown.ioc.User">value="张三">
e>"setlistvalue1""setlistvalue2"
创建测试类;importorg.springframework.conte
xt.ApplicationContext;importorg.springframework.context.support.
ClassPathXmlApplicationContext;publicclassXmlBeanAssembleTest{
publicstaticvoidmain(String[]args){ApplicationContextappl
icationContext=newClassPathXmlApplicationContext("applicationC
ontext.xml");//构造方式输出结果System.out.println(applicationContext.g
etBean("user1"));//设值方式输出结果System.out.println(applicationConte
xt.getBean("user2"));}}2.5.2基于Annotation的装配基于XML的装配可能会导致XML配置文件
过于臃肿,给后续的维护和升级带来一定的困难。为此,Spring提供了对Annotation(注解)技术的全面支持。@Compone
nt:用于描述Spring中的Bean,它是一个泛化的概念,仅仅表示一个组件。@Repository:用于将数据访问层(DAO)的
类标识为Spring中的Bean。@Service:用于将业务层(Service)的类标识为Spring中的Bean。@Cont
roller:用于将控制层(Controller)的类标识为Spring中的Bean。@Autowired:用于对Bean的属性
变量、属性的setter方法及构造方法进行标注,配合对应的注解处理器完成Bean的自动配置工作。@Resource:其作用与Aut
owired一样。@Resource中有两个重要属性:name和type。Spring将name属性解析为Bean实例名称,typ
e属性解析为Bean实例类型。@Qualifier:与@Autowired注解配合使用,会将默认的按Bean类型装配修改为按Bea
n的实例名称装配,Bean的实例名称由@Qualifier注解的参数指定。在这个实例中需要引入:spring-aop-4.3.6.
RELEASE.jar创建接口UserDao,并定义方法;packagecom.unknown.AnnotationTest;p
ublicinterfaceUserDao{publicvoidsave();}创建接口实现类UserDaoImpl,
用@Repository声明类;packagecom.unknown.AnnotationTest;importorg.spr
ingframework.stereotype.Repository;@Repository("userDao")publicc
lassUserDaoImplimplementsUserDao{publicvoidsave(){System.o
ut.println("userdao...save...");}}创建接口UserService,并定义方法;package
com.unknown.AnnotationTest;publicinterfaceUserService{public
voidsave();}创建接口实现类UserServiceImpl,用@Service声明类,并使用@Resource注入Us
erDao属性;packagecom.unknown.AnnotationTest;importorg.springframe
work.stereotype.Service;importjavax.annotation.Resource;@Service
("userService")publicclassUserServiceImplimplementsUserServic
e{@Resource(name="userDao")privateUserDaouserDao;publicv
oidsave(){//调用userDao中的save方法this.userDao.save();System.out.
println("userservice....save...");}}创建控制器类,用@Controller声明,并使用@Re
source注入UserService属性;packagecom.unknown.AnnotationTest;importo
rg.springframework.stereotype.Controller;importjavax.annotation.
Resource;@Controller("userController")publicclassUserController
{@Resource(name="userService")privateUserServiceuserServic
e;publicvoidsave(){this.userService.save();System.out.print
ln("userController...save...");}}配置bean;base-package="com.unknown.AnnotationTest"/>:这一段内容是扫描该包下的所有类id="userDao"class="com.unknown.AnnotationTest.UserDaoImpl"/>anid="userService"class="com.unknown.AnnotationTest.UserService
Impl"/>st.UserController"/>这一段是指定了对应关系上面两部分,任选其一使用,也可以同时使用"1.0"encoding="UTF-8"?>org/schema/beans"xmlns:xsi="http://www.w3.org/2001/XMLSchema-ins
tance"xmlns:context="http://www.springframework.org/schema/conte
xt"xsi:schemaLocation="http://www.springframework.org/schema/bea
nshttp://www.springframework.org/schema/beans/spring-beans-4.3.x
sdhttp://www.springframework.org/schema/contexthttp://www.sprin
gframework.org/schema/context/spring-context-4.3.xsd">-分别定义3个Bean实例-->nTest.UserDaoImpl"/>notationTest.UserServiceImpl"/>com.unknown.AnnotationTest.UserController"/>kage="com.unknown.AnnotationTest"/>创建测试类,测试程序。importcom.
unknown.AnnotationTest.UserController;importorg.springframework.
context.ApplicationContext;importorg.springframework.context.sup
port.ClassPathXmlApplicationContext;publicclassAnnotationAssemb
leTest{publicstaticvoidmain(String[]args){//加载配置文件Appli
cationContextapplicationContext=newClassPathXmlApplicationCon
text("applicationContext.xml");//获取UserController实例UserControl
leruserController=(UserController)applicationContext.getBean(
"userController");//调用UserController中的save()方法userController.s
ave();}}2.5.3自动装配所谓自动装配,就是将一个Bean自动的注入到到其他Bean的Property中。Sprin
g的元素中包含一个autowire属性,我们可以通过设置autowire的属性值来自动装配Bean。autowire属
性有5个值,其值及说明下表所示:修改上一节UserServiceImpl,添加setter方法packagecom.unknow
n.AnnotationTest;importorg.springframework.stereotype.Service;im
portjavax.annotation.Resource;@Service("userService1")publiccla
ssUserServiceImplimplementsUserService{@Resource(name="use
rDao")privateUserDaouserDao;publicvoidsave(){//调用userDao中
的save方法this.userDao.save();System.out.println("userservice....s
ave...");}publicvoidsetUserDao(UserDaouserDao){this.userDa
o=userDao;}}修改上一节UserController,添加setter方法packagecom.unknown.
AnnotationTest;importorg.springframework.stereotype.Controller;i
mportjavax.annotation.Resource;@Controller("userController")publ
icclassUserController{@Resource(name="userService")private
UserServiceuserService;publicvoidsave(){this.userService.s
ave();System.out.println("userController...save...");}public
voidsetUserService(UserServiceuserService){this.userService=
userService;}}配置bean;nsxmlns="http://www.springframework.org/schema/beans"xmlns:xsi=
"http://www.w3.org/2001/XMLSchema-instance"xsi:schemaLocation="h
ttp://www.springframework.org/schema/beanshttp://www.springframe
work.org/schema/beans/spring-beans.xsd">UserDaoImpl"/>创建测试类,测试程序。importcom.unknown.AnnotationTest.UserController;importorg.springframework.context.ApplicationContext;importorg.springframework.context.support.ClassPathXmlApplicationContext;publicclassAnnotationAssembleTest{publicstaticvoidmain(String[]args){//加载配置文件ApplicationContextapplicationContext=newClassPathXmlApplicationContext("applicationContext.xml");//获取UserController实例UserControlleruserController=(UserController)applicationContext.getBean("userController");//调用UserController中的save()方法userController.save();}}2.6本章小结本章对Spring的Bean进行了详细讲解,首先介绍了Bean的配置,然后通过案例讲解了Bean实例化的三种方式,接下来介绍了Bean的作用域和生命周期,最后讲解了Bean的三种装配方式。通过本章的学习,要求读者了解Bean的装配过程,并能使用Bean的装配进行开发。本章作业请简述Bean的生命周期。请简述Bean的几种装配方式的基本用法。预习作业什么是AOP?Spring有哪些通知类型?
献花(0)
+1
(本文系大量资料原创)