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的主要内容,如果未能解决你的问题,请参考以下文章