Spring配置bean

Posted 逢甘霖成大事

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了Spring配置bean相关的知识,希望对你有一定的参考价值。

基本

<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans"
	xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
	xmlns:util="http://www.springframework.org/schema/util"
	xmlns:p="http://www.springframework.org/schema/p"
	xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans.xsd
		http://www.springframework.org/schema/util http://www.springframework.org/schema/util/spring-util-4.0.xsd">

	<!-- 属性注入的方式,依赖seter方法,name2并不是属性名,而是由setName2()得来的 -->
	<bean id="person" class="model.Person">
		<property name="name2" value="JJ"></property>
	</bean>
	<!-- 构造器注入的方式,依赖bean中对应的构造方法,可以指定顺序和类型,都不指定的话就会自动按照顺序注入,不会自动对照类型 -->
	<bean id="car1" class="model.Car">
		<constructor-arg index="0" type="java.lang.String" value="Auto"></constructor-arg>
		<constructor-arg index="1" type="java.lang.String" value="DaZhong"></constructor-arg>
		<constructor-arg index="2" type="java.lang.Integer" value="200"></constructor-arg>
	</bean>
	<bean id="car2" class="model.Car">
		<constructor-arg index="0" type="java.lang.String" value="BieKe"></constructor-arg>
		<constructor-arg index="1" type="java.lang.String" value="TongYong"></constructor-arg>
		<constructor-arg index="2" type="java.lang.Double" value="200000.0"></constructor-arg>
	</bean>
	
	<bean id="person_car1" class="model.Person_Car">
		<constructor-arg type="java.lang.String" >
			<!-- 想指定的字符串中有特殊字符的情况 -->
			<value><![CDATA[<QQ>]]></value>
		</constructor-arg>
		<!-- ref:引用上面定义过的对象 -->
		<constructor-arg type="model.Car" ref="car1"></constructor-arg>
		<!-- 也可以以这种方式为引用对象赋值(级联的方式) -->
		<property name="car.price" value="1"></property>
	</bean>
	
	<bean id="person_car2" class="model.Person_Car">
		<property name="name">
			<value><![CDATA[<WW>]]></value>
		</property>
		<property name="car">
			<!-- 为内部引用单独定义对象,外部引用不到,所以可以不写id -->
			<bean class="model.Car">
				<constructor-arg index="0" value="HaFu"></constructor-arg>
				<constructor-arg index="1" value="ChangCheng"></constructor-arg>
				<constructor-arg type="java.lang.Double" value="100000.0"></constructor-arg>
				<property name="maxSpeed" value="100"></property>
			</bean>
		</property>
		<!-- 赋空值的方式 -->
		<property name="car.brand"><null></null></property>
		<property name="Car.corp" value="ZhongTai"></property>
	</bean>
	
	<!-- 若属性为数组或者list时的 -->
	<bean id="person_collectioncar" class="model.Person_CollectionCar">
		<constructor-arg value="EE"></constructor-arg>
		<constructor-arg>
			<list>
				<ref bean="car1"/>
				<ref bean="car2"/>
			</list>
		</constructor-arg>
	</bean>
	
	<!-- 若属性为Map时的 -->
	<bean id="person_mapcar" class="model.Person_MapCar">
		<property name="name" value="RR"></property>
		<property name="cars">
			<map>
				<entry key="11" value-ref="car1"></entry>
				<entry key="22" value-ref="car2"></entry>
			</map>
		</property>
	</bean>
	<!-- 若属性为properties时 -->
	<bean id="person_propertiescar" class="model.Person_PropertiesCar">
		<property name="name" value="TT"></property>
		<property name="cars">
			<!-- 同样外部无法引用 -->
			<props>
				<prop key="33">JIYUNFEI</prop>
				<prop key="44">wangshu321</prop>
			</props>
		</property>
	</bean>
	<bean id="person_propertiescar2" class="model.Person_PropertiesCar">
		<property name="name" value="TT"></property>
		<property name="cars" ref="pp"></property>
	</bean>
	
	<!-- 需要先打开util命名空间,可以定义properties,list,map,数组等类型的属性,方便上面引用 -->
	<util:properties id="pp">
		<prop key="33">JIYUNFEI</prop>
		<prop key="55">jiyunfei</prop>
	</util:properties>
	<!-- 需要先打开p命名空间,以这种方式可以更方便定义bean -->
	<bean id="person_propertiescar3" class="model.Person_PropertiesCar" p:name="CC" p:cars-ref="pp"></bean>
</beans>
package helloSpring;

import org.springframework.context.ApplicationContext;
import org.springframework.context.support.ClassPathXmlApplicationContext;

import model.Person_CollectionCar;
import model.Person_MapCar;
import model.Person_PropertiesCar;

public class Main {
	public static void main(String[] args) {
//		Person p = new Person();
//		p.setName("Ji");
		
		ApplicationContext context = new ClassPathXmlApplicationContext("applicationContext.xml");
//		Person p = (Person) context.getBean("person");
//		Person p = context.getBean(Person.class);
//		p.hello();
		
		/**
		 * ApplicationContext获取bean的三种方式
		 * (Person) context.getBean("person")	需要强转
		 * context.getBean("car1", Car.class)	不需要强转
		 * context.getBean(Car.class)			要求xml中这种类型只能有一个
		 * */
		
//		Car car1 = context.getBean("car1", Car.class);
//		Car car2 = context.getBean("car2", Car.class);
//		System.out.println(car1);
//		System.out.println(car2);
		
//		Person_Car p1 = (Person_Car) context.getBean("person_car1");
//		Person_Car p2 = (Person_Car) context.getBean("person_car2");
//		System.out.println(p1);
//		System.out.println(p2);
		
		Person_CollectionCar person_CollectionCar = context.getBean(Person_CollectionCar.class);
		Person_MapCar person_MapCar = context.getBean(Person_MapCar.class);
		Person_PropertiesCar person_PropertiesCar = context.getBean("person_propertiescar",Person_PropertiesCar.class);
		System.out.println(person_CollectionCar);
		System.out.println(person_MapCar);
		System.out.println(person_PropertiesCar);
		
		Person_PropertiesCar person_PropertiesCar2 = context.getBean("person_propertiescar2",Person_PropertiesCar.class);
		System.out.println(person_PropertiesCar2);
		
		Person_PropertiesCar person_PropertiesCar3 = context.getBean("person_propertiescar3",Person_PropertiesCar.class);
		System.out.println(person_PropertiesCar3);
	}
}

自动注入

<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans"
	xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
	xmlns:util="http://www.springframework.org/schema/util"
	xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans.xsd
		http://www.springframework.org/schema/util http://www.springframework.org/schema/util/spring-util-4.0.xsd">

	<!-- 
	<bean id="address" class="autowire.Address">
		<property name="city" value="AnYang"></property>
		<property name="street" value="EMei"></property>
	</bean>
	 -->
	<bean id="address2" class="autowire.Address">
		<property name="city" value="BeiJing"></property>
		<property name="street" value="ChangAn"></property>
	</bean>
	<bean id="car" class="autowire.Car">
		<property name="name" value="Audi"></property>
		<property name="price" value="1"></property>
	</bean>
	
	<bean id="car2" class="autowire.Car">
		<property name="name" value="Audi"></property>
		<property name="price" value="1"></property>
	</bean>
	
	<util:list id="cars">
		<ref bean="car"/>
		<ref bean="car2"/>
	</util:list>
	<!-- 以下为person自动装配它的引用类型的属性 -->
	<!-- byName:通过bean的id和seter方法中的名字匹配来自动注入属性值,并且自动注入的值还可以被覆盖修改 -->
	<!-- byType:用过与其他Bean的类型的匹配来注入属性值,此时要求:符合匹配类型的Bean只能有一个,否则会抛异常 -->
	<bean id="person" class="autowire.Person" autowire="byType">
		<property name="name" value="JJ"></property>
		<!-- <property name="address" ref="address2"></property> -->
	</bean>
	
</beans>

bean的作用域

<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://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.xsd">

	<!-- 
	Bean的作用域
	默认为"singleton":表示此bean时单例的,在创建ApplicationContext对象时就调用了构造方法创建
	"prototype":是原型的意思。每次get到的bean都不是一个。在每次执行ctx.getBean(Car.class);时都调用构造方法新创建一个
	 -->
	<bean id="car" class="autowire.Car" scope="prototype">
		<property name="name" value="Audi"></property>
		<property name="price" value="1"></property>
	</bean>
	
</beans>

bean之间关系

<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans"
	xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
	xmlns:util="http://www.springframework.org/schema/util"
	xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans.xsd
		http://www.springframework.org/schema/util http://www.springframework.org/schema/util/spring-util-4.0.xsd">

	<!-- 
	address和address2时继承关系
	若想address只是作为被继承的父Bean可以将其设置为abstract,此时address是抽象的,在获取时抛异常
	 -->
	 
	<bean id="address" abstract="true">
		<property name="city" value="AnYang"></property>
		<property name="street" value="EMei"></property>
	</bean>
	<bean id="address2" class="autowire.Address" parent="address">
		<property name="street" value="ChangAn"></property>
	</bean>
	
	<!-- 依赖 -->
	
	<bean id="car" class="autowire.Car">
		<property name="name" value="Audi"></property>
		<property name="price" value="1"></property>
	</bean>
	
	<bean id="car2" class="autowire.Car">
		<property name="name" value="Audi"></property>
		<property name="price" value="1"></property>
	</bean>
	
	<util:list id="cars">
		<ref bean="car"/>
		<ref bean="car2"/>
	</util:list>
	
	<!-- 
	依赖
	depends-on="car" 
	表示person这个bean依赖与一个id为car的bean,在加载IOC容器时,若在xml中没有id为car的bean抛异常
	 -->
	
	<!-- 
		若有depends-on,则IOC容器在创建bean时会按先创建car再创建person的顺序;
		若没有depends-on,有ref,那么在ref时若被引用的对象不存在,那么会在这时创建被引用的对象
		若没有depends-on也没有ref,那么按照从上到下的顺序创建bean
		
		带有scope="prototype"的bean在被用到时才会创建(被其他bean引用也算用到),且每次都创建一个新的。
		
		
		
	 -->
	
	<bean id="person" class="autowire.Person" depends-on="car">
		<property name="name" value="JJ"></property>
		<property name="address" ref="address2"></property>
	</bean>
	
</beans>

bean的生命周期

<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans"
	xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
	xmlns:p="http://www.springframework.org/schema/p"
	xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans.xsd">


	<!-- 
		Perosn‘s constructor
		 setAddress 
		setName
		BeforeInit person
		AA
		AfterInit person
		在ClassPathXmlApplicationContext关闭或者销毁时调用BB
	 -->
	<bean id="person" class="cycle.Person" p:address-ref="address" p:name="Ji"
		init-method="AA" destroy-method="BB"
		depends-on="address"></bean>
	
	<!-- 
		Address‘s constructor
		setCity
		setStreet
		BeforeInit address
		init
		AfterInit address
		在ClassPathXmlApplicationContext关闭或者销毁时调用destroy
	 -->
	<bean id="address" class="cycle.Address" init-method="intit" destroy-method="destroy"
		p:city="#{‘HuBei‘}" p:street="WuHan"
		></bean>
	
	<!-- 
		public class PostProcessor implements BeanPostProcessor
		Bean 的后置处理器
		Bean 后置处理器允许在调用初始化方法前后对 Bean 进行额外的处理.
		Bean 后置处理器对 IOC 容器里的所有 Bean 实例逐一处理, 而非单一实例. 
				其典型应用是: 检查 Bean 属性的正确性或根据特定的标准更改 Bean 的属性.
		对Bean 后置处理器而言, 需要实现BeanPostProcessor接口. 
				在初始化方法被调用前后, Spring 将把每个 Bean 实例分别传递给上述接口的以下两个方法:
				postProcessAfterInitialization	postProcessBeforeInitialization
	 -->
	<bean class="cycle.PostProcessor"></bean>
</beans>

添加外部文件

<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans"
	xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
	xmlns:context="http://www.springframework.org/schema/context"
	xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans.xsd
		http://www.springframework.org/schema/context http://www.springframework.org/schema/context/spring-context-4.0.xsd">
	
	<!-- 以这种方式添加外部文件 classpath:db.properties(需添加context命名空间) -->
	<context:property-placeholder location="classpath:db.properties"/>
	
	<!-- 以这种方式访问外部文件中的数据 -->
	<!-- 意外发现${}中用username得到的是电脑名字JI -->
	<bean id="dataSource" class="com.mchange.v2.c3p0.ComboPooledDataSource">
		<property name="user" value="${name}"></property>
		<property name="password" value="${passWord}"></property>
		<property name="driverClass" value="${driverClass}"></property>
		<property name="jdbcUrl" value="${jdbcUrl}"></property>
	</bean>
	
</beans>

另外三种工厂方法配置bean

<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans"
	xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
	xmlns:p="http://www.springframework.org/schema/p"
	xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans.xsd">

	<!-- 
	静态工厂方法配置bean的方法,要求是静态属性,静态方法
	此时class="factoryPeiZhiBean.StaticFactory",为静态工厂全类名,但此时通过Address.class来getBean依然没问题
	factory-method="getInstance" 返回address的静态方法
	<constructor-arg value="beijing"></constructor-arg>为静态方法的参数
	 -->
	<bean id="address" class="factoryPeiZhiBean.StaticFactory"  factory-method="getInstance">
		<constructor-arg value="beijing"></constructor-arg>
	</bean>
	<bean id="address4" class="factoryPeiZhiBean.Address" >
		<property name="city" value="#{T(factoryPeiZhiBean.StaticFactory).getInstance(‘jiaozuo‘).getCity()}"></property>
		<property name="street" value="#{T(factoryPeiZhiBean.StaticFactory).getInstance(‘beijing‘).getStreet()}"></property>
	</bean>
	
	
	<!-- 
		工厂方法配置bean
		需要先有一个factory的bean,所以此时factory中属性和方法不需要是静态
	 -->
	<bean id="factory" class="factoryPeiZhiBean.Factory"></bean>
	<!-- class="factoryPeiZhiBean.Address"	自己的全类名 -->
	<bean id="address2" class="factoryPeiZhiBean.Address" factory-bean="factory" factory-method="getInstance">
		<constructor-arg value="jiaozuo"></constructor-arg>
	</bean>
	
	
	<!-- 
		通过FactoryBean的方式配置bean
		public class FactoryBean implements org.springframework.beans.factory.FactoryBean<Address>
	 -->
	<bean id="address3" class="factoryPeiZhiBean.FactoryBean">
		<property name="shengming" value="HuBei"></property>
		<property name="shiming" value="WuHan"></property>
	</bean>
	
</beans>

spEL

<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://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.xsd">
	
	<bean id="address" class="spEL.Address">
	
		<!-- 表示字面量 -->		
		<property name="city" value="#{‘beijing‘}"></property>
		<property name="street" value="ChangAn"></property>
	</bean>
	
	
	<bean id="car" class="spEL.Car">
		<property name="name" value="Audi"></property>
		<property name="price" value="200001"></property>
		<property name="r" value="100"></property>
		<!-- 
		可以用T访问一个类的 静态 变量。
		
		也可以级联的方式访问本bean的属性值,如下的r读出来是原本定义中的0.5而不是上面刚配置的100
		也可以级联的方式访问其他bean的属性值,但该值必须是明确的,且不一定是在类定义中确定的
		 -->
		<property name="zhouchang" value="#{T(java.lang.Math).PI * car.r * 2}"></property>
	</bean>
	
	<bean id="person" class="spEL.Person">
		<property name="name" value="JJ"></property>
		
		<!-- 等同于ref -->
		<property name="car" value="#{car}"></property>
		
		<!-- 可以使用其他bean的属性值,如果使用自己的,则为null,因为自己本身此属性就是null -->
		
		<property name="city" value="#{address.city}"></property>
		
		<!-- 可以使用其他bean的方法,如果使用自己的,则为null,因为ioc容器通过反射得到的bean对象的引用属性就是null -->
		<property name="info" value="#{person2.getCar().panduan()}"></property>
	</bean>
	
	<bean id="person2" class="spEL.Person">
		<property name="name" value="YY"></property>
		<property name="car" value="#{car}"></property>
		<property name="city" value="#{address.city}"></property>
		
		<!-- 也可以使用三目运算符 -->
		<property name="info" value="#{car.price > 200000 ? ‘金领‘ : ‘白领‘}"></property>
	</bean>

</beans>

用注解的方式配置bean

<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans"
	xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
	xmlns:context="http://www.springframework.org/schema/context"
	xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans.xsd
		http://www.springframework.org/schema/context http://www.springframework.org/schema/context/spring-context-4.0.xsd">

	<!-- 
	用注解的方式配置bean
	1,需要先导入spring-aop-4.0.0.RELEASE.jar包
	2,   @Component
		public class Aa
	
	@Component: 基本注解, 标识了一个受 Spring 管理的组件
	@Repository: 标识持久层组件
	@Service: 标识服务层(业务层)组件
	@Controller: 标识表现层组件
	对于扫描到的组件, Spring 有默认的命名策略: 使用非限定类名, 第一个字母小写. 
	也可以在注解中通过 value 属性值标识组件的名称
	 -->
	<!-- 
		组件扫描(component scanning):  Spring 能够从 classpath 下自动扫描, 侦测和实例化具有特定注解的组件. 
		base-package="annotation":指定扫描的包
		resource-pattern="*.class":可以指定扫描 包或者子包中 适合匹配的类
		
	 -->
	 
	<context:component-scan base-package="annotation"
		resource-pattern="*.class" use-default-filters="true">
		<!-- 按不同的注解 去配置指定的bean。若想只配置指定的bean要和use-default-filters="false"配合使用
		<context:include-filter type="annotation" expression="org.springframework.stereotype.Repository"/>
		 -->
		 <!-- 按不同的注解 不去配置指定的bean。
		<context:exclude-filter type="annotation" expression="org.springframework.stereotype.Controller"/>
		 -->
		 <!-- 按不同的类 -->
		 <!-- 
		 <context:include-filter type="assignable" expression="annotation.Cc"/>
		 <context:exclude-filter type="assignable" expression="annotation.Rr"/>
		  -->
	</context:component-scan>
	
	
	<!-- 
		@Autowired 标注在属性或者set方法上面,表示自动装配。
		其装配是先按照类型,若有多个匹配类型(继承或者实现接口)则会按照名字。
		若@Repository("rrr")起的名字并不规范,那么可以public void setRr(@Qualifier("rrr") Rr rr) {}
	 -->
</beans>

  

  

  

  

  

  

  

  

  

  

以上是关于Spring配置bean的主要内容,如果未能解决你的问题,请参考以下文章

05Spring源码-手写篇-手写Bean配置

Spring装配bean--02通过Java代码装配bean

Spring配置Bean

05Spring源码-手写篇-手写Bean配置

05Spring源码-手写篇-手写Bean配置

Spring二 Bean详解