Spring xml基本配置

1.通过setter方式注入

	<!-- 配置一个 bean -->
	<bean id="helloWorld2" class="com.atguigu.spring.helloworld.HelloWorld">
		<!-- 为属性赋值 -->
		<!-- 通过属性注入: 通过 setter 方法注入属性值 -->
		<property name="user" value="Tom"></property>
	</bean>


2.通过构造器注入
	<!-- 通过构造器注入属性值 -->
	<bean id="helloWorld3" class="com.atguigu.spring.helloworld.HelloWorld">
		<!-- 要求: 在 Bean 中必须有对应的构造器.  -->
		<constructor-arg value="Mike"></constructor-arg>
	</bean>


3.若一个 bean有多个构造器可以根据 index value进行更加精确的定位.

	<bean id="car" class="com.atguigu.spring.helloworld.Car">
		<constructor-arg value="KUGA" index="1"></constructor-arg>
		<constructor-arg value="ChangAnFord" index="0"></constructor-arg>
		<constructor-arg value="250000" type="float"></constructor-arg>
	</bean>


4.若字面值中包含特殊字符,则可以使用 DCDATA来进行赋值.

	<bean id="car2" class="com.atguigu.spring.helloworld.Car">
		<constructor-arg value="ChangAnMazda"></constructor-arg>
		<!-- 若字面值中包含特殊字符, 则可以使用 DCDATA 来进行赋值. (了解) -->
		<constructor-arg>
			<value><![CDATA[<ATARZA>]]></value>
		</constructor-arg>
		<constructor-arg value="180" type="int"></constructor-arg>
	</bean>

5.通过ref 属性值指定当前属性指向哪一个 bean

	<!-- 配置 bean -->
	<bean id="dao5" class="com.atguigu.spring.ref.Dao"></bean>

	<bean id="service" class="com.atguigu.spring.ref.Service">
		<!-- 通过 ref 属性值指定当前属性指向哪一个 bean! -->
		<property name="dao" ref="dao5"></property>
	</bean>

6.声明内部bean

	<!-- 声明使用内部 bean -->
	<bean id="service2" class="com.atguigu.spring.ref.Service">
		<property name="dao">
			<!-- 内部 bean, 类似于匿名内部类对象. 不能被外部的 bean 来引用, 也没有必要设置 id 属性 -->
			<bean class="com.atguigu.spring.ref.Dao">
				<property name="dataSource" value="c3p0"></property>
			</bean>
		</property>
	</bean>



7.设置级联属性

	<bean id="action" class="com.atguigu.spring.ref.Action">
		<property name="service" ref="service2"></property>
		<!-- 设置级联属性(了解) 设置 service属性的dao属性的dataSource属性-->
		<property name="service.dao.dataSource" value="DBCP2"></property>
	</bean>

8.设置 属性值为 null

	<bean id="dao2" class="com.atguigu.spring.ref.Dao">
		<!-- 为 Dao 的 dataSource 属性赋值为 null, 若某一个 bean 的属性值不是 null, 使用时需要为其设置为 null(了解) -->
		<property name="dataSource"><null/></property>
	</bean>

9.配置List,Map,Properties

(1)在bean内部声明,声明后,即使给内部bean声明了id,其余bean也不可使用

	<!-- 装配集合属性 -->
	<bean id="user" class="com.atguigu.spring.helloworld.User">
		<property name="userName" value="Jack"></property>
		<property name="cars">
			<!-- 使用 list 元素来装配集合属性 -->
			<list>
				<ref bean="car"/>
				<ref bean="car2"/>
			</list>
		</property>
	</bean>
(2)在外部声明集合类型的 bean,再引用

	<!-- 声明集合类型的 bean -->
	<util:list id="cars">
		<ref bean="car"/>
		<ref bean="car2"/>
	</util:list>
	
	<bean id="user2" class="com.atguigu.spring.helloworld.User">
		<property name="userName" value="Rose"></property>
		<!-- 引用外部声明的 list -->
		<property name="cars" ref="cars"></property>
	</bean>

10.使用p命名空间

使用p命名空间可简化 通过setter注入的写法

	<bean id="user3" class="com.atguigu.spring.helloworld.User"
		p:cars-ref="cars" p:userName="Titannic"></bean>

11.继承映射

(1)使用 parent 来完成继承,继承后,子bean可以覆盖从父bean继承过来的配置

(2)父bean作为模板,可设置bean 的abstract属性为true,这样spring不会实例化这个bean

(3)并不是<bean>元素里的所有属性都会被继承,比如autowire,abstract

(4)也可忽略父bean的class属性,让子bean设定自己的类,但此时abstruct属性必须为true

	<bean id="user" class="com.atguigu.spring.helloworld.User">
		<property name="userName" value="Jack"></property>
		<property name="cars">
			<!-- 使用 list 元素来装配集合属性 -->
			<list>
				<ref bean="car"/>
				<ref bean="car2"/>
			</list>
		</property>
	</bean>
	<bean id="user4" parent="user" p:userName="Bob"></bean>

12.bean之间的依赖关系

Spring允许用户通过depends-on属性设定bean前置依赖的bean,前置依赖的bean会在本bean实例化前创建好

如果前置依赖多个bean,可通过逗号,或空格的方式配置bean的名称

	<bean id="user6" parent="user" p:userName="维多利亚"></bean>
	
	<!-- 测试 depents-on -->	
	<bean id="user5" parent="user" p:userName="Backham" depends-on="user6"></bean>
此示例中user5依赖于user6,


13.自动装配

Spring IOC容器可自动装配bean,需要在bean的autowire属性里指定自动装配的模式

byType(根据类型自动装配):若IOC容器中有多个与目标bean类型一致的bean,不能执行自动装配,会报错

byName(根据名称自动装配):必须目标bean的id和属性名设置的完全相同,若没有 id 一致的, 则无法完成自动装配

constructor:不推荐使用

(1)byName

Service类

public class Service {

	private Dao dao;
	
	public void setDao(Dao dao) {
		this.dao = dao;
	}
	
	public Dao getDao() {
		return dao;
	}
	
	public void save(){
		System.out.println("Service's save");
		dao.save();
	}
	
}
xml配置文件

	<!-- 在使用 XML 配置时, 自动装配用的不多. 但在基于 注解 的配置时, 自动装配使用的较多.  -->
	<bean id="dao" class="com.atguigu.spring.ref.Dao">
		<property name="dataSource" value="C3P0"></property>				
	</bean>
	<bean id="dao2" class="com.atguigu.spring.ref.Dao"></bean>
	
	<bean id="service" class="com.atguigu.spring.ref.Service" autowire="byName"></bean>
此示例将自动注入id为 dao 的bean,给id为 service 的bean

(2)byType

Action类

public class Action {

	private Service service;
	
	public void setService(Service service) {
		this.service = service;
	}
	
	public Service getService() {
		return service;
	}
	
	public void execute(){
		System.out.println("Action's execute...");
		service.save();
	}
	
}
xml配置文件
	<bean id="service" class="com.atguigu.spring.ref.Service" autowire="byName"></bean>
	
	<bean id="action" class="com.atguigu.spring.ref.Action" autowire="byType"></bean>
	

14.bean的作用域

可以通过 scope 属性来指定 bean 的作用域

prototype: 原型的. 每次调用 getBean 方法都会返回一个新的 bean. 且在第一次调用 getBean 方法时才创建实例
singleton: (默认值)单例的. 在 IOC 容器初始化时即创建 bean 的实例.  在整个容器的生命周期内,只创建一个bean

	<bean id="dao2" class="com.atguigu.spring.ref.Dao" scope="prototype"></bean>


15.使用外部属性文件

Spring 提供了一个PropertyPlaceholderConfigurer的 BeanFactory 后置处理器,这个处理器允许用户将Bean配置的部分内容外移到 属性文件中.可以在Bean配置文件里使用形式为 ${ var } 的变量,PropertyPlaceholderConfigurer从属性文件里加载属性,并使用这些属性来替换变量.
示例:

(1).类路径下新建  db.properties 配置文件存放配置信息

jdbc.user=root
jdbc.password=1230
jdbc.driverClass=com.mysql.jdbc.Driver
jdbc.jdbcUrl=jdbc:mysql:///test

jdbc.initPoolSize=5
jdbc.maxPoolSize=10
(2).xml配置文件中导入外部属性文件,并使用文件中的属性(需使用context命名空间)

	<!-- 导入外部的资源文件 -->
	<context:property-placeholder location="classpath:db.properties"/>
	
	<!-- 配置数据源 -->
	<bean id="dataSource" class="com.mchange.v2.c3p0.ComboPooledDataSource">
		<property name="user" value="${jdbc.user}"></property>
		<property name="password" value="${jdbc.password}"></property>
		<property name="driverClass" value="${jdbc.driverClass}"></property>
		<property name="jdbcUrl" value="${jdbc.jdbcUrl}"></property>
		
		<property name="initialPoolSize" value="${jdbc.initPoolSize}"></property>
		<property name="maxPoolSize" value="${jdbc.maxPoolSize}"></property>
	</bean>

16.SpEL

语法类似于EL:SpEL使用 # {…}作为定界符,所有在大框号中的字符都将被认为是SpEL
SpEL作用:

(1)字面量表示

整数:<propertyname="count" value=" #{5 }"/>
String:

String可以使用单引号或者双引号作为字符串的定界符

<property name=“name” value="#{'Chuck'}"/>或<property name='name' value='#{"Chuck"}'/>

其余类型略...

(2)引用其他对象

(3)引用其他对象的属性

(4)调用其他方法,还可以链式操作

<!--通过value属性和spel    配置suffix属性值为另一个Bean的方法的返回值-->

<property name="suffix" value="#{sequenceGeneator.toString()}"></property>

(5)算数运算符:+,-, *, /, %, ^  (加号还可以用作字符串连接)

(6)比较运算符:<, >, ==, <=, >=, lt,gt,eq,le, ge

(7)逻辑运算符号: and, or, not

(8)if-else 运算符

(9)正则表达式:matches

(10)调用静态方法或静态属性:通过T() 调用一个类的静态方法,它将返回一个ClassObject,然后再调用相应的方法或属性: 

示例:

	<bean id="address" class="com.test.spel.Address">
		<!-- 使用spel为属性赋一个字面值 -->
		<property name="city" value="#{'beijing'}"></property>
		<property name="street" value="huilongguan"></property>
	</bean>
	
	<bean id="car" class="com.test.spel.Car">
		<property name="brand" value="Audi"></property>
		<property name="price" value="500000"></property>
		<!-- 使用SpEL引用类的静态属性 -->
		<property name="tyrePerimeter" value="#{T(java.lang.Math).PI * 80}"></property>
	</bean>

	<bean id="person" class="com.test.spel.Person">
		<!-- 使用spel引用一个其他的bean -->
		<property name="car" value="#{car}"></property>
		<!-- 使用spel引用一个其他bean的属性 -->
		<property name="city" value="#{address.city}"></property>
		<!-- 在spel中使用运算符 -->
		<property name="info" value="#{car.price>300000? '金领':'白领'}"></property>
		<property name="name" value="Tom"></property>
	</bean>

17.Bean生命周期

(1)Spring IOC 容器对 Bean的生命周期进行管理的过程:
通过构造器或工厂方法创建 Bean实例 (构造方法)
为 Bean 的属性设置值和对其他Bean的引用 (setter方法)
调用 Bean 的初始化方法(init-method)
Bean 可以使用了
当容器关闭时 , 调用 Bean 的销毁 方法(destroy-method)
示例:

Car实体类

public class Car {
	private String brand;

	public String getBrand() {
		return brand;
	}

	public void setBrand(String brand) {
		System.out.println("setter...");
		this.brand = brand;
	}
	
	
	public Car(){
		System.out.println("constructor...");
	}
	
	public void init(){
		System.out.println("init...");
	}
	
	public void destory(){
		System.out.println("destory...");
	}
}
xml配置文件

	<!-- 初始化方法:init-method   销毁方法:destroy-method -->
	<bean id="car" class="com.test.cycle.Car"
		init-method="init" destroy-method="destory">
		<property name="brand" value="Audi"/>
	</bean>
测试类:

	public static void main(String[] args) {
		ClassPathXmlApplicationContext ctx=new ClassPathXmlApplicationContext("beans-cycle.xml");
		Car car=(Car) ctx.getBean("car");
		
		System.out.println(car);
		
		ctx.close();
	}
结果:

先打印constructor...,再打印setter...,再打印init...,再打印com.test.cycle.Car@9317ccb,最后打印destory...


(2)Bean的后置处理器

Bean 后置处理器允许在调用初始化方法前后对 Bean 进行额外的处理 .
Bean 后置处理器对 IOC 容器里的 所有Bean 实例逐一处理,而非单一实例.其典型应用是:检查Bean属性的正确性或根据特定的标准更改Bean的属性.
使用方法

1.实现接口BeanPostProcessor

public class MyBeanPostProcesser implements BeanPostProcessor{

	/**
	 * init-method之前调用
	 */
	@Override
	public Object postProcessAfterInitialization(Object bean, String beanName)
			throws BeansException {
		System.out.println("postProcessAfterInitialization:" + beanName);
		return bean;
	}

	/**
	 * init-method之后调用
	 */
	@Override
	public Object postProcessBeforeInitialization(Object bean, String beanName)
			throws BeansException {
		System.out.println("postProcessBeforeInitialization:" + beanName);
		return bean;
	}

}
2.配置bean后置处理器

	<!-- 实现接口 BeanPostProcessor 并提供
		postProcessBeforeInitialization(Object bean, String beanName)	init-method之前被调用
		postProcessAfterInitialization(Object bean, String beanName)	init-method之后被调用
		方法的实现
	 -->
	<!-- 配置bean的后置处理器,不需要配置id,IOC容器自动识别是一个 BeanPostProcesser-->
	<bean class="com.test.cycle.MyBeanPostProcesser"></bean>



18.通过工厂方法配置bean

(1)静态工厂方法(不需要创建工厂的对象)

实体类Car

public class Car {
	private String brand;
	private int price;
	public String getBrand() {
		return brand;
	}
	public void setBrand(String brand) {
		this.brand = brand;
	}
	public int getPrice() {
		return price;
	}
	public void setPrice(int price) {
		this.price = price;
	}
	public Car(String brand, int price) {
		super();
		this.brand = brand;
		this.price = price;
	}
	
	public Car() {
	}
}
静态工厂StaticCarFactory
/**
 * 静态工厂方法
 * @author SkyWalker
 *
 */
public class StaticCarFactory {
	private static Map<String,Car> cars=new HashMap<>();
	
	static{
		cars.put("Audi", new Car("Audi",300000));
		cars.put("Ford", new Car("Ford",400000));
	}
	
	public static Car getCar(String name) {
		return cars.get(name);
	}
}
xml配置文件

	<!-- 通过静态工厂方法 配置bean实例 -->
	<!-- 
		class属性:指向静态工厂方法的全类名
		factory-method:指向静态工厂方法的名字
		constructor-arg:如果静态工厂方法需传入参数,则使用constructor-arg来配置参数
	 -->
	<bean id="car1" class="com.spring.test.factory.StaticCarFactory"
		factory-method="getCar">
		<constructor-arg value="Audi"></constructor-arg>
	</bean>

(2)实例工厂(需创建工厂的对象)

实体类Car:同上

实例工厂InstanceCarFactory

/**
 * 实例工厂方法
 * @author SkyWalker
 *
 */
public class InstanceCarFactory {
	private Map<String,Car> cars=null;
	
	public InstanceCarFactory() {
		cars=new HashMap<>();
		cars.put("Audi", new Car("Audi",300000));
		cars.put("Ford", new Car("Ford",400000));
	}
	
	public Car getCar(String brand) {
		return cars.get(brand);
	}
}
xml配置文件
		<!-- 配置实例工厂 -->
		<!-- 
		factory-bean属性:指向实例工厂发方法的bean
		factory-method:指向静态工厂方法的名字
		constructor-arg:如果静态工厂方法需传入参数,则使用constructor-arg来配置参数
	 	-->
		<bean id="carFactory" class="com.spring.test.factory.InstanceCarFactory"></bean>
		<!-- 通过实例工厂方法来配置bean -->
		<bean id="car2" factory-bean="carFactory" factory-method="getCar">
			<constructor-arg value="Ford"></constructor-arg>
		</bean>


19.Spring 通过FactoryBean配置Bean

步骤:

1.实体类Car

public class Car {
	private String brand;
	private int price;
	public String getBrand() {
		return brand;
	}
	public void setBrand(String brand) {
		this.brand = brand;
	}
	public int getPrice() {
		return price;
	}
	public void setPrice(int price) {
		this.price = price;
	}
	public Car(String brand, int price) {
		super();
		this.brand = brand;
		this.price = price;
	}
	
	public Car() {
	}
}

2.写自定义的FactoryBean需要实现FactoryBean的接口

//自定义的FactoryBean 需要实现FactoryBean的接口
public class CarFactoryBean implements FactoryBean<Car>{
	private String brand;
	
	
	public void setBrand(String brand) {
		this.brand = brand;
	}

	/**
	 * 返回bean的对象
	 */
	@Override
	public Car getObject() throws Exception {
		// TODO Auto-generated method stub
		return new Car(brand,500000);
	}

	/**
	 * 返回bean的类型
	 */
	@Override
	public Class<?> getObjectType() {
		return Car.class;
	}

	/**
	 * 是否单例
	 */
	@Override
	public boolean isSingleton() {
		return true;
	}

}

3.xml配置文件

<!-- 
	通过FactoryBean来配置Bean的实例
	class: 指向FactoryBean的全类名
	property:配置FactoryBean的属性
	
	但实际返回FactoryBean的getObject()方法返回的实例
 -->
<bean id="car" class="com.spring.factorybean.CarFactoryBean">
	<property name="brand" value="BMW"></property>
</bean>

















猜你喜欢

转载自blog.csdn.net/qq_34763699/article/details/53729640