Spring学习第三天:配置Bean-1
2016-09-16 11:04
381 查看
内容:
在Spring的IOC容器里配置Bean
在xml文件中通过bean节点来配置bean
id: bean的名称
- 在IOC容器中必须是唯一的
- 若id没有指定,Spring自动将类名作为Bean的名字
- id可以指定多个名字,名字之间可用逗号,分号,或空格分隔
Spring容器
在Spring IOC容器读取Bean配置创建Bean实例之前,必须对他进行实例化,只有在容器实例化之后,才可以从IOC容器里获取Bean实例并使用。
Spring提供了两种类型的IOC容器实现
- BeanFactory, IOC的基本实现
- ApplicationContext 提供了更多的高级特性,是BeanFactory的子接口
- BeanFactory是Spring框架的基础设施,面向Spring本身;ApplicationContext面向使用Spring框架的开发者,几乎所有的应用场合都直接使用ApplicationContext而非底层的BeanFactory
- 无论使用何种方式,配置文件是相同的
AplicationContext介绍
ApplicationContext的主要实现类:
- ClassPathXmlApplicationContext, 从类路径下加载配置文件
- FileSystemXmlApplicationContext,从文件系统中加载配置文件
ConfigurableContext扩展于ApplicationContext,新增加两个主要方法:refresh()和close() ,让ApplicationContext具有启动,刷新和关闭上下文的能力。
ApplicationContext在初始化上下文时就实例化所有实例的Bean
WebApplicationContext是专门为WEB应用而准备的,它允许从相对于WEB根目录的路径中完成初始化工作
代码实例:
上述提到的,如果配置文件中有两个同一类型的bean,如下
则会遇到如下错误
从IOC容器中获取Bean的方式可以调用ApplicationContext的getBean()方法。
依赖注入的方式
Spring支持三种依赖注入的方式
- 属性注入
- 构造器注入
- 工厂方法注入(很少使用,不推荐)
属性注入
属性注入即通过setter方法注入Bean的属性值或依赖的对象
属性注入使用property元素,使用name属性指定Bean的属性名称,value属性或value子节点指定属性值
属性注入是实际应用中最常用的注入方式
Note: 因为属性注入是依赖于setter方法注入的,所以Bean类必须为变量提供setter方法。
构造器方式注入
通过构造方法注入Bean的属性值或依赖的对象,他保证了Bean实例在实例化后就可以使用
构造器注入在 constructor-arg元素中申明属性,constructor-arg 中没有name属性
新建一个Car类
该类中使用构造器初始化Car类中的三个参数
xml文件配置:
调用这个Bean
输出如下结果:
上述的index可有可无,没有的话则按照构造器中参数的顺序自动注入。
如果再配置一个构造器:
配置XML文件
调用Bean
输出结果
可见,并没有按照我们预想的,把240赋值给maxSpeed。
此时,仅仅依靠默认顺序,是无法识别重载的构造器的。 我们可以使用标签type去区别。
xml配置如下:
运行结果如下:
从输出结果可知,使用构造器注入属性值的时候可以指定参数的位置和参数的类型,以区分重载构造器。
index 表示 构造器中的位置,0表示构造器第一个参数
type表示构造器中参数的类型。
这两者可以结合使用。
Note:与属性注入不同的是,使用构造器注入必须提供带参数的构造器。
配置形式:基于XML文件的方式;基于注解的方式 Bean的配置方法:通过全类名(反射),通过工厂方式(静态工厂方式&实例工厂方式),FactoryBean IOC容器BeanFactory&ApplicationContext概述 依赖注入的方式:属性注入,构造器注入 注入属性值细节 自动转配 Bean之间的关系:继承,依赖 Bean的作用域:singleton,prototype,WEB环境作用域 使用外部属性文件 spEL IOC容器中Bean的生命周期 Spring4.x新特性:泛型依赖注入
在Spring的IOC容器里配置Bean
在xml文件中通过bean节点来配置bean
<!-- 通过全类名的方式配置bean --> <!-- class: bean的全类名,表示是通过反射的方式在IOC容器中创建bean实例。所以要求在HelloWorld中必须有一个无参的构造函数,如果不存在这个无参的构造器,那么就会编译出错 --> <!-- id: 标志容器中的bean,id唯一 --> <bean id="helloWorld" class="com.atguigu.spring.beans.HelloWorld" > <property name="name" value="World"></property> </bean>
id: bean的名称
- 在IOC容器中必须是唯一的
- 若id没有指定,Spring自动将类名作为Bean的名字
- id可以指定多个名字,名字之间可用逗号,分号,或空格分隔
Spring容器
在Spring IOC容器读取Bean配置创建Bean实例之前,必须对他进行实例化,只有在容器实例化之后,才可以从IOC容器里获取Bean实例并使用。
Spring提供了两种类型的IOC容器实现
- BeanFactory, IOC的基本实现
- ApplicationContext 提供了更多的高级特性,是BeanFactory的子接口
- BeanFactory是Spring框架的基础设施,面向Spring本身;ApplicationContext面向使用Spring框架的开发者,几乎所有的应用场合都直接使用ApplicationContext而非底层的BeanFactory
- 无论使用何种方式,配置文件是相同的
AplicationContext介绍
ApplicationContext的主要实现类:
- ClassPathXmlApplicationContext, 从类路径下加载配置文件
- FileSystemXmlApplicationContext,从文件系统中加载配置文件
ConfigurableContext扩展于ApplicationContext,新增加两个主要方法:refresh()和close() ,让ApplicationContext具有启动,刷新和关闭上下文的能力。
ApplicationContext在初始化上下文时就实例化所有实例的Bean
WebApplicationContext是专门为WEB应用而准备的,它允许从相对于WEB根目录的路径中完成初始化工作
代码实例:
// 创建Spring 的IOC 容器 // ApplicationContext 代表IOC容器 // ClassPathXmlApplicationContext: 是ApplicationContext 接口的实现类,该实现类从类路径下来加载配置文件 ApplicationContext ctx = new ClassPathXmlApplicationContext("applicationContext.xml"); //从IOC容器中获取bean实例 //通过id 定位到IOC容器中的bean HelloWorld helloWorld = (HelloWorld) ctx.getBean("helloWorld2"); //通过类型返回IOC容器中的bean,但要求IOC容器中必须只能有一个该类型的bean HelloWorld helloWorld2 = (HelloWorld) ctx.getBean(HelloWorld.class);
上述提到的,如果配置文件中有两个同一类型的bean,如下
<!-- 配置bean --> <bean id="helloWorld" class="com.atguigu.spring.beans.HelloWorld" > <property name="name" value="World"></property> </bean> <bean id="helloWorld2" class="com.atguigu.spring.beans.HelloWorld" > <property name="name" value="World"></property> </bean>
则会遇到如下错误
Exception in thread "main" org.springframework.beans.factory.NoUniqueBeanDefinitionException: No qualifying bean of type [com.atguigu.spring.beans.HelloWorld] is defined: expected single matching bean but found 2: helloWorld,helloWorld2 at org.springframework.beans.factory.support.DefaultListableBeanFactory.getBean(DefaultListableBeanFactory.java:312) at org.springframework.context.support.AbstractApplicationContext.getBean(AbstractApplicationContext.java:985) at com.atguigu.spring.beans.Main.main(Main.java:18)
从IOC容器中获取Bean的方式可以调用ApplicationContext的getBean()方法。
依赖注入的方式
Spring支持三种依赖注入的方式
- 属性注入
- 构造器注入
- 工厂方法注入(很少使用,不推荐)
属性注入
属性注入即通过setter方法注入Bean的属性值或依赖的对象
属性注入使用property元素,使用name属性指定Bean的属性名称,value属性或value子节点指定属性值
属性注入是实际应用中最常用的注入方式
<bean id="helloWorld" class="com.atguigu.spring.beans.HelloWorld" > <property name="name" value="World"></property> </bean>
Note: 因为属性注入是依赖于setter方法注入的,所以Bean类必须为变量提供setter方法。
构造器方式注入
通过构造方法注入Bean的属性值或依赖的对象,他保证了Bean实例在实例化后就可以使用
构造器注入在 constructor-arg元素中申明属性,constructor-arg 中没有name属性
新建一个Car类
public class Car { private String brand; private String corp; private double price; private int maxSpeed; public Car(String brand, String corp, double price) { super(); this.brand = brand; this.corp = corp; this.price = price; } @Override public String toString() { // TODO Auto-generated method stub return brand + " " + corp + " " + price + " " + maxSpeed; } }
该类中使用构造器初始化Car类中的三个参数
xml文件配置:
<!-- 通过构造方法来配置Bean的属性 --> <!-- 可以使用index下标确定那个属性 --> <bean id="car" class="com.atguigu.spring.beans.Car"> <constructor-arg value="Audi"></constructor-arg> <constructor-arg value="Shanghai" index="1"></constructor-arg> <constructor-arg value="300000" index="2"></constructor-arg> </bean>
调用这个Bean
Car car = ctx.getBean(Car.class); System.out.println(car);
输出如下结果:
Audi Shanghai 300000 0
上述的index可有可无,没有的话则按照构造器中参数的顺序自动注入。
如果再配置一个构造器:
public Car(String brand, String corp, int maxSpeed) { super(); this.brand = brand; this.corp = corp; this.maxSpeed = maxSpeed; }
配置XML文件
<bean id="car2" class="com.atguigu.spring.beans.Car"> <constructor-arg value="baoma"></constructor-arg> <constructor-arg value="Shanghai" index="1"></constructor-arg> <constructor-arg value="240" index="2"></constructor-arg> </bean>
调用Bean
Car car = (Car) ctx.getBean("car"); System.out.println(car); car = (Car) ctx.getBean("car2"); System.out.println(car);
输出结果
Audi Shanghai 300000.0 0 baoma Shanghai 240.0 0
可见,并没有按照我们预想的,把240赋值给maxSpeed。
此时,仅仅依靠默认顺序,是无法识别重载的构造器的。 我们可以使用标签type去区别。
xml配置如下:
<bean id="car2" class="com.atguigu.spring.beans.Car"> <constructor-arg value="baoma"></constructor-arg> <constructor-arg value="Shanghai"></constructor-arg> <constructor-arg value="240" type="int"></constructor-arg> <!-- 或者采用<value>的方法--> <constructor-arg type="int"> <value>240</value> </constructor-arg> </bean>
运行结果如下:
Audi Shanghai 300000.0 0 baoma Shanghai 0.0 240
从输出结果可知,使用构造器注入属性值的时候可以指定参数的位置和参数的类型,以区分重载构造器。
index 表示 构造器中的位置,0表示构造器第一个参数
type表示构造器中参数的类型。
这两者可以结合使用。
Note:与属性注入不同的是,使用构造器注入必须提供带参数的构造器。
相关文章推荐
- spring学习笔记整理--04(配置Spring管理的bean的作用域、生命周期)
- 学习《Spring实战(第3版)》扎记1:Spring使用注解配置Bean的方式
- Spring2.5学习1.1_bean配置及其Spring容器的实例化
- Spring4 学习笔记(3)-Spring 基于 XML 的方式配置 Bean(供自己学习)
- Spring学习(16)--- 基于Java类的配置Bean 之 基于泛型的自动装配(spring4新增)
- Spring学习笔记 使用XML配置实现Bean的auto-wiring (自动绑定)
- Spring学习系列之――第三章:Spring中Bean的配置(一)
- Spring学习(13)--- 基于Java类的配置Bean 之 @Configuration & @Bean注解
- spring学习笔记(4)——配置文件配置bean自动装配
- Spring学习篇02-Bean的xml配置
- Spring学习之Bean的配置
- Spring学习笔记之bean配置
- spring学习5-注解式bean配置+Junit简易使用
- Spring学习(14)--- 基于Java类的配置Bean 之 @ImportResource & @Value 注解
- Spring学习笔记(7)-----------Bean的基本配置
- Java 学习笔记04:Spring XML配置文件Bean
- Spring4学习笔记-通过注解配置bean
- spring学习4-bean配置文件
- Spring学习(九)使用ioc注解方式配置bean
- Spring学习(15)--- 基于Java类的配置Bean 之 @Bean & @Scope 注解