//www.springframework.org/schema/beans"
xmlns:
xsi="http:
//www.w3.org/2001/XMLSchema-instance"
xsi:
schemaLocation="http:
//www.springframework.org/schema/beans
http:
//www.springframework.org/schema/beans/spring-beans-3.0.xsd">
xml文件中设置了bean,包含在和中。
每个bean都有一个唯一的id。
测试类:
publicclassTestEntity{
publicstaticvoidmain(String[]args){
ApplicationContextcontext=newClassPathXmlApplicationContext(
"applicationContext.xml");
Usersu=(Users)context.getBean("u");
//u.setName("小白");
System.out.println(u);
}
}
以上的案例?
IOC(DI)配置及应用
一、什么是IOC、DI
IOC:
InversionofControl控制反转:
其作用是实例化具体的bean,动态装配bean
三种说法:
①原来类的一些成员属性(例如UserService中的userDao成员属性)是由当前类(UserService)自己控制,现在不是由当前类(UserService)自己控制,而是由容器(运行环境上下文、Spring)帮我们来控制。
②原来我们自己控制是控制实现,而现在Spring是利用接口来控制的。
所以我们由原来控制实现转为spring现在来控制接口(向上反转).
③当一对象需要依赖另外一个对象时,通常用调用对来来创建被调用对象的实例,在Spring中,创建被调用对象的工作不再由调用对象来完成,而是由Spring容器来完成,然后注入调用对象,这就是控制反转。
由以上说法可知:
本来是由我(应用程序本身)来控制的,现在我交给容器(Spring)来控制。
IoC很好的体现了面向对象设计法则之一,好莱坞法则:
“别找我们,我们找你”。
DI:
DependencyInjection依赖注入:
一些成员属性(例如UserService中的userDao成员属性)依赖Spring容器来注入
好处:
是spring的核心机制,可以使Spring的bean以配置文件组织在一起,而不是硬编码方式耦合,耦合性相对来降低了;另外,注入是使用配置文件来实现,这样修改来非常的方便.
举例理解IOC?
大家想想咯…
DI与IOC相对来说是一样的概念。
当然有时候,我们也说,IOC其实是一种设计模式,而DI是一种具体的实现方式。
SpringIoc容器解析:
SpringIoc容器的代表就是org.springframework.beans包中的BeanFactory接口,BeanFactory接口提供了IoC容器最基本功能;而org.springframework.context包下的ApplicationContext接口扩展了BeanFactory,还提供了与SpringAOP集成、国际化处理、事件传播及提供不同层次的context实现(如针对web应用的WebApplicationContext)。
简单说,BeanFactory提供了IoC容器最基本功能,而ApplicationContext则增加了更多支持企业级功能支持。
ApplicationContext完全继承BeanFactory,因而BeanFactory所具有的语义也适用于ApplicationContext。
容器实现一览:
•XmlBeanFactory:
BeanFactory实现,提供基本的IoC容器功能,可以从classpath或文件系统等获取资源;
(1)Filefile=newFile("fileSystemConfig.xml");
Resourceresource=newFileSystemResource(file);
BeanFactorybeanFactory=newXmlBeanFactory(resource);
(2)
Resourceresource=newClassPathResource("classpath.xml");BeanFactorybeanFactory=newXmlBeanFactory(resource);
•ClassPathXmlApplicationContext:
ApplicationContext实现,从classpath获取配置文件;
BeanFactorybeanFactory=
newClassPathXmlApplicationContext("classpath.xml");
•FileSystemXmlApplicationContext:
ApplicationContext实现,从文件系统获取配置文件。
BeanFactorybeanFactory=
newFileSystemXmlApplicationContext("fileSystemConfig.xml");
ApplicationContext接口获取Bean方法简介:
•ObjectgetBean(Stringname)根据名称返回一个Bean,客户端需要自己进行类型转换;
•TgetBean(Stringname,ClassrequiredType)根据名称和指定的类型返回一个Bean,客户端无需自己进行类型转换,如果类型转换失败,容器抛出异常;
•TgetBean(ClassrequiredType)根据指定的类型返回一个Bean,客户端无需自己进行类型转换,如果没有或有多于一个Bean存在容器将抛出异常;
•MapgetBeansOfType(Classtype)根据指定的类型返回一个键值为名字和值为Bean对象的Map,如果没有Bean对象存在则返回空的Map。
IoC容器到底是如何工作的呢?
①配置文件的准备工作:
在配置文件applicationContext.xml中声明Bean,也就是为Bean配置元数据。
②IoC容器解析元数据:
IoC容器的BeanReader读取并解析配置文件,根据定义生成BeanDefinition配置元数据对象,IoC容器根据BeanDefinition进行实例化、配置及组装Bean。
③实例化IoC容器:
由客户端实例化容器,获取需要的Bean。
二、Bean的标识
SpringIoC容器目的就是管理Bean,这些Bean将根据配置文件中的Bean定义进行创建,而Bean定义在容器内部由BeanDefinition对象表示,该定义主要包含以下信息:
●全限定类名(FQN):
用于定义Bean的实现类;
●Bean行为定义:
这些定义了Bean在容器中的行为;包括作用域(单例、原型创建)、是否惰性初始化及生命周期等;
●Bean创建方式定义:
说明是通过构造器还是工厂方法创建Bean;
●Bean之间关系定义:
即对其他bean的引用,也就是依赖关系定义,这些引用bean也可以称之为同事bean或依赖bean,也就是依赖注入。
一般配置文件结构如下:
1、标签主要用来进行Bean定义;
2、alias用于定义Bean别名的;
3、import用于导入其他配置文件的Bean定义,这是为了加载多个配置文件,当然也可以把这些配置文件构造为一个数组(newString[]{“config1.xml”,config2.xml})传给ApplicationContext实现进行加载多个配置文件,那一个更适合由用户决定;这两种方式都是通过调用BeanDefinitionReader读取Bean定义,内部实现没有任何区别。
标签可以放在下的任何位置,没有顺序关系。
注xml配置文件中标签中的属性名称如下:
或
标签中的属性id与name作用是一样,区别在于id中不可以含有特殊字符,而name中可以有特殊字符;id是确定该bean的唯一属性,而name可以指定一个或者多个名称,各个名称之间用逗号或分号分开。
后面的为bean的别名。
测试如下代码功能:
xmlversion="1.0"encoding="UTF-8"?
>
//www.springframework.org/schema/beans"
xmlns:
xsi="http:
//www.w3.org/2001/XMLSchema-instance"
xsi:
schemaLocation="http:
//www.springframework.org/schema/beans
http:
//www.springframework.org/schema/beans/spring-beans-3.0.xsd">
--第一种写法只包含了class-->
--第二种写法包含了idclass-->
--第三种写法包含了nameclass-->
--第四种写法包含了class-->
--m4的别名-->
测试类:
/**
*
*@authorknowno
*
*/
publicclassTestMessage{
@Test
publicvoidiocTest01()
{
BeanFactorybf=newClassPathXmlApplicationContext("applicationContext.xml");
Messagem=bf.getBean(Message.class);
System.out.println(m);
}
@Test
publicvoidiocTest02()
{
BeanFactorybf=newClassPathXmlApplicationContext("applicationContext.xml");
Messagem=(Message)bf.getBean("m2");
System.out.println(m);
}
@Test
publicvoidiocTest03()
{
BeanFactorybf=newClassPathXmlApplicationContext("applicationContext.xml");
Messagem=(Message)bf.getBean("m3");
System.out.println(m);
}
@Test
publicvoidiocTest04()
{
BeanFactorybf=newClassPathXmlApplicationContext("applicationContext.xml");
Messagem=(Message)bf.getBean("malias");
System.out.println(m);
}
}
∙Bean命名约定:
Bean的命名遵循XML命名规范,但最好符合Java命名规范,由“字母、数字、下划线组成“,而且应该养成一个良好的命名习惯,比如采用“驼峰式”,即第一个单词首字母开始,从第二个单词开始首字母大写开始,这样可以增加可读性。
三、注入类型(Injectingdependencies)
1、setter(重要)
2、构造方法(了解)
3、接口注入(了解)
(一)setter注入类型
就是在bean中使用setXXX方法进行注入来
在bean类中,成员属性需要setXXX方法如下:
publicclassUserService{
privateUserDaoud;
publicUserDaogetUd(){
returnud;
}
publicvoidsetUd(UserDaoud){
this.ud=ud;
}
publicvoidaddUser(Usersu){
ud.addUser(u);
}
}
(二)构造方法
首先在bean类中需要有成员属性作为参数的构造方法
代码如下:
publicclassUserService{
privateUserDaouserDao=newUserDaoImpl();
publicUserService(UserDaouserDao){
super();
this.userDao=userDao;
}
publicUserDaogetUserDao(){returnuserDao;}
publicvoidsetUserDao(UserDaouserDao){this.userDao=userDao;}
publicvoidadd(Useru){userDao.save(u);}
}
注意:
背景较深的代码为构造方法,带有参数的构造方法
spring配置文件如下:
使用的[进行构造方法注入]
当构造方法注入时,构造方法中有多个参数时,可以使用以下两种方式注入:
bean代码:
publicclassExampleBean{
privateintyears;
privateStringultimateAnswer;
publicExampleBean(intyears,StringultimateAnswer){
this.years=years;
this.ultimateAnswer=ultimateAnswer;
}
}
1、参数类型方式进行区分参数:
xml配置文件:
注意:
这样就是参数类型为int的注入7500000,而参数类型为java.lang.String的参数注入”42”,但这个方法不适合多个参数是相同的类型。
2、使用索引
xml配置文件