Spring装配Bean

XML方式装配Bean

装配Bean的方式分为通过XML装配和通过注解装配两种方式。通过xml装配是指在XML文件中添加bean元素,这里不详细讨论,只给出一个简单的例子:

<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-4.0.xsd">
	<bean id="source" class="com.ssm.chapter9.pojo.Source">
		<property name="fruit" value="橙汁" />
		<property name="sugar" value="少糖" />
		<property name="size" value="大杯" />
	</bean>

	<bean id="juiceMaker2" class="com.ssm.chapter9.pojo.JuiceMaker2">
		<property name="beverageShop" value="贡茶" />
		<property name="source" ref="source" />
	</bean>
</beans>

和一个属性为集合的例子:

<bean id="role1" class="com.ssm.chapter10.pojo.Role">
	<property name="id" value="1" />
	<property name="roleName" value="role_name_1" />
	<property name="note" value="role_note_1" />
</bean>

<bean id="role2" class="com.ssm.chapter10.pojo.Role">
	<property name="id" value="2" />
	<property name="roleName" value="role_name_2" />
	<property name="note" value="role_note_2" />
</bean>

<bean id="user1" class="com.ssm.chapter10.pojo.User">
	<property name="id" value="1" />
	<property name="userName" value="user_name_1" />
	<property name="note" value="role_note_1" />
</bean>

<bean id="user2" class="com.ssm.chapter10.pojo.User">
	<property name="id" value="2" />
	<property name="userName" value="user_name_2" />
	<property name="note" value="role_note_1" />
</bean>

<bean id="userRoleAssembly" class="com.ssm.chapter10.pojo.UserRoleAssembly">
	<property name="id" value="1" />
	<property name="list">
		<list>
			<ref bean="role1" />
			<ref bean="role2" />
		</list>
	</property>
	<property name="map">
		<map>
			<entry key-ref="role1" value-ref="user1" />
			<entry key-ref="role2" value-ref="user2" />
		</map>
	</property>
	<property name="set">
		<set>
			<ref bean="role1" />
			<ref bean="role2" />
		</set>
	</property>
</bean>
  • 还有一种是XML中使用命名空间装配Bean,不再详细介绍。
注解方式转配Bean
  • 下面讨论通过注解的方式装配Bean,首先介绍第一个注解@Component,该注解放在需要被Spirng IoC管理的Bean的类上方。
  • 第二个注解是@ComponentScan,该注解放在配置类(Java Config)的上面,用来告诉Spring哪些包里面的类是需要被扫描的。这些包里面所有被@Component注解修饰的类都会被装配。
  • 给一个简单的例子,分别看看两个注解所在的位置。
package com.ssm.chapter10.annotation.pojo;

import org.springframework.beans.factory.annotation.Value;
import org.springframework.stereotype.Component;

@Component(value = "role")//value相当于xml中的id
public class Role {
	@Value("1")//属性注入,注入简单的值
	private Long id;
	@Value("role_name_1")
	private String roleName;
	@Value("role_note_1")
	private String note;
	/** getter and setter **/

Java Config类

package com.ssm.chapter10.annotation.pojo;

import org.springframework.context.annotation.ComponentScan;

//注解@ComponentScan的属性basePackageClasses或者basePackages用来指明需要扫描的包以及子包。
@ComponentScan(basePackageClasses = { Role.class, RoleServiceImpl.class })
// @ComponentScan(basePackages = {"com.ssm.chapter10.annotation.pojo",
// "com.ssm.chapter10.annotation.service"})
public class PojoConfig {

}

有了这两部分,就能够通过Spring定义好的Spring IoC容器的实现类——AnnotationConfigApplicationContext去生成IoC容器了:

ApplicationContext context = new AnnotationConfigApplicationContext(PojoConfig.class);
Role role = context.getBean(Role.class);//再通过ApplicationContext中的getBean方法得到bean对象
System.err.println(role.getId());

前面的Role类的属性是比较简单的,如果遇到了稍微复杂点的属性,我们通常是用自动装配的方式,而不是在属性上面加@Value注解。

注解方式装配Bean之使用@Bean注解

@Component注解是放在类之上,而@Bean注解则放到方法之上,并将方法返回的对象作为Spring的Bean,存放在IoC容器中。例如DBCP数据源:

@Bean(name = "dataSource")//当Spring IoC容器扫描它的时候,就会为其生成对应的Bean
public DataSource getDataSource() {
	Properties props = new Properties();
	props.setProperty("driver", "com.mysql.jdbc.Driver");
	props.setProperty("url", "jdbc:mysql://localhost:3306/chapter10");
	props.setProperty("username", "root");
	props.setProperty("password", "123456");
	DataSource dataSource = null;
	try {
		dataSource = BasicDataSourceFactory.createDataSource(props);
	} catch (Exception e) {
		e.printStackTrace();
	}
	return dataSource;
}
自动装配——@Autowired

自动装配技术是由Spring自己发现对应的Bean,自动完成装配工作(属性注入)。例如下面的RoleService2类中的role属性。

package com.ssm.chapter10.annotation.service.impl;

import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Component;

import com.ssm.chapter10.annotation.pojo.Role;
import com.ssm.chapter10.annotation.service.RoleService2;

@Component("RoleService2")
public class RoleServiceImpl2 implements RoleService2 {

	@Autowired//加在需要自动寻找对象并注入的属性上方,也可以是它的setter方法上。
	private Role role = null;

	public Role getRole() {
		return role;
	}

//	@Autowired
	public void setRole(Role role) {
		this.role = role;
	}

	@Override
	public void printRoleInfo() {
		System.out.println("id =" + role.getId());
		System.out.println("roleName =" + role.getRoleName());
		System.out.println("note =" + role.getNote());
	}
}

@Autowired注解是按照类型进行寻找并注入的,当属性为接口,而接口又不止一个实现类时就会报错,为了消除歧义,还有另外一个注解@Qualifier(“beanName”),放在属性的上面:

package com.ssm.chapter10.annotation.controller;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Qualifier;
import org.springframework.stereotype.Component;

import com.ssm.chapter10.annotation.pojo.Role;
import com.ssm.chapter10.annotation.service.RoleService;

@Component
public class RoleController {
	
	@Autowired
	@Qualifier("roleService3")
	private RoleService roleService = null;
	
	public void printRole(Role role) {
		roleService.printRoleInfo(role);
	}
}

此时,属性注入就会按照名字查找的方式,而非类型匹配的方式。实际上,这两种方式分别对应底层接口的两个方法。那就是BeanFactory的getBean方法:

<T> T getBean(Class<T> requiredType) throws BeansException;
Object getBean(String name) throws BeansException;
装配的混合使用

一般情况下我们都会两种同时使用,这时候需要将XML配置文件引入到注解的体系当中,引入时使用注解,放置的位置时是配置类(Java Config)的上面,跟@ComponentScan注解在一起。例如:

package com.ssm.chapter10.annotation.pojo;

import org.springframework.context.annotation.ComponentScan;
import org.springframework.context.annotation.ImportResource;

//注解@ComponentScan的属性basePackageClasses或者basePackages用来指明需要扫描的包以及子包。
//@ComponentScan(basePackageClasses = { Role.class, RoleServiceImpl.class })
@ComponentScan(basePackages = {"com.ssm.chapter10.annotation"})
@ImportResource({"classpath:spring-dataSource.xml"})
public class ApplicationConfig {

}

加入@ImportResource这个注解后,就能够在需要注入数据库连接池属性时通过@Autowired注解自动注入。spring-dataSource.xml的内容如下:

<?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-4.0.xsd">
	<bean id="dataSource1" class="org.apache.commons.dbcp.BasicDataSource">
		<property name="driverClassName" value="com.mysql.jdbc.Driver" />
		<property name="url" value="jdbc:mysql://localhost:3306/chapter10" />
		<property name="username" value="root" />
		<property name="password" value="123456" />
	</bean>
</beans>
多XML文件或多配置类引用

有时候我们会分开定义多个xml配置文件或者多个配置类,这时就需要在其中一个中引入其他。配置类的引用方式如下:

import org.springframework.context.annotation.ComponentScan;
import org.springframework.context.annotation.Import;

//注解@ComponentScan的属性basePackageClasses或者basePackages用来指明需要扫描的包以及子包。
//@ComponentScan(basePackageClasses = { Role.class, RoleServiceImpl.class })
@ComponentScan(basePackages = {"com.ssm.chapter10.annotation"})
@Import({ApplicationConfig2.class,ApplicationConfig3.class})//引入配置类
public class ApplicationConfig {

}

xml的引入方式如下:

<import resource="spring-datasource.xml"/>
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值