Spring基础:IoC容器(1)

[size=x-large][b]在IoC容器中装配Bean[/b][/size]

4.1.2.RELEASE版本的Spring支持3种配置方式
[list]
[*]基于XML配置
[*]基于注解
[*]基于Java类
[/list]

1.基于XML的配置
这种方式是经典方式,即使Spring不断发展,也必须向前兼容这种方式。装配一个Bean有3种方式。
1.1 属性注入
这种方式是最常用的方式,基于POJO类中的Set方法,为属性注入参数。

public class Car {
private int maxSpeed;
private String brand;
private double price;
// Getter Setter
// introduce方法将各参数打印出来
}


<bean id="car" class="com.firethewhole.maventest05.ditype.Car">
<property name="maxSpeed"><value>100</value></property>
<property name="brand"><value>红旗CA97</value></property>
<property name="price"><value>20000.00</value></property>
</bean>

可以在main方法中使用如下方法可以访问

ApplicationContext application = new ClassPathXmlApplicationContext("applicationContext.xml");
Car car = (Car) application.getBean("car");
System.out.println(car.introduce());

[color=red]*****需要注意的是,在配置Bean的Property时,比如<property name="brand"/>,Spring仅要求必须存在setBrand()方法,不一定要拥有brand成员变量[/color]

1.2 构造函数注入
1.2.1 按构造函数的参数的类型进行匹配入参

public Car(String brand, double price) {
this.brand = brand;
this.price = price;
}


<bean id="car" class="com.firethewhole.maventest05.ditype.Car">
<constructor-arg type="java.lang.String">
<value>红旗CA72</value>
</constructor-arg>
<constructor-arg type="int">
<value>70</value>
</constructor-arg>
<constructor-arg type="double">
<value>20000</value>
</constructor-arg>
</bean>

[color=red]****注意,这种方式,根据入参类型就可以确定如何绑定的情况下不需要保证顺序和Java构造方法的参数顺序一致。[/color]

1.2.2 按索引匹配入参
如果入参存在两个相同类型的参数,那使用上面一种方式就没办法唯一确定了,这个时候需要根据入参的索引来确定,第一个参数的索引是"0",第二个是"1",一次类推

<bean id="car" class="com.firethewhole.maventest05.ditype.Car"><bean id="car" class="com.firethewhole.maventest05.ditype.Car">
<constructor-arg index="0" value="红旗CA72" />
<constructor-arg index="1" value="中国一汽" />
<constructor-arg index="2" value="20000" />
</bean>


1.2.3 联合使用类型和索引匹配入参
如果分别使用上面两种方式还是没有办法绑定,比如有多个构造函数,其中有一个参数类型不同,这种情况下可以联合使用上面两种方法。

1.2.4 通过反射匹配入参
如果入参的类型是可以辨别的,比如自定义的Car类,Office类这种,在构造函数中引用了这些类,在XML配置的时候,可以不加type和index,由框架自动注入。

public Boss(String name, Car car, Office office) {
// 省略
}


<bean id="boss" type="com.firethewhole.maventest05.ditype.Boss">
<consturctor-arg>
<value>John</value>
</constructor-arg>
<constructor-arg>
<ref bean="car"/>
</constructor-arg>
<constructor-arg>
<ref bean="office"/>
</constructor-arg>
</bean>
<bean id="car" class="com.firethewhole.maventest05.ditype.Car"/>
<bean id="office" class="com.firethewhole.maventest05.ditype.Office"/>


1.3 工厂方法注入
分静态工厂方法和非静态工厂方法,这种方法在IoC中用的不多,就跳过不提了。

2.基于注解的方式
基于XML的方式实在过繁杂,书写起来也容易犯错,所以现在更多的是使用基于注解的方式。
在使用基于注解的方式配置Bean之前,需要先告诉Spring有哪些程序包是需要被扫描的
<context-component-scan base-package="com.firethewhole.maventest05.anno/>
以上只是最简单的方式,还可以在其中配置和除外和包含的基于正则或其他方式的匹配。

然后在Bean定义时,对类加上@Component,@Repository,@Service,@Controller之类的注解即可。
对类中定义的属性可以使用@Autowired进行自动注入,会按照优先类型匹配的方式进行自动注入。

required属性,在没有匹配的时候也不会报错,这个值默认是true
@Qualifier注解可以指定注入的Bean的名称,
@Scope注解Bean的作用范围
@PostConstruct,@PreDestroy对应init-method和destroy-method

3.基于Java类的注解
这种方式由@Configuration注解定义配置文件Java类,通过@Bean进行Bean的定义。通常对程序员更加友好。
3.1 标准方式

@Configuration
public class AppConf {
@Bean
public UserDao userDao() {
return new UserDao();
}

@Bean
public LogDao logDao() {
return new LogDao();
}

@Bean
public LogonService logonService() {
LogonService logonService = new LogonService();
logonService.setUserDao(userDao());// 看下面注释
logonService.setLogDao(logDao());
return logonService;
}
}


通过以下方式可以启动容器

ApplicationContext ctx = new AnnotationConfigApplicationContext(AppConf.class);
LogonService logonService = ctx.getBean(LogonService.class);
logonService.printHello();


[color=red]像上面这个例子里面,UserDao和LogDao实际上是加上了Getter Setter方法的,实际上没必要在这两个Dao中加上Setter方法,只需要在LogonService中给这两个属性加上@Autowired注解,就会自动注入了。[/color]

3.2 多Config文件组合

@Configuration
public class DaoConfig {
@Bean
public UserDao userDao() {
return new UserDao();
}

@Scope("prototype")
@Bean
public LogDao logDao() {
return new LogDao();
}
}

@Configuration
@Import(DaoConfig.class) // 使用这行代码就就可以引用其他的注解配置类
public class ServiceConfig {
@Autowired
private DaoConfig daoConfig;

@Bean
public LogonService logonService() {
LogonService logonService = new LogonService();
// 这里没有加上Setter方法,是因为LogonService中使用了Autowired注解
return logonService;
}
}


如下,如果没有使用Import注解的话,需要在启动容器的时候,把所有的Java注解配置类都注册上

AnnotationConfigApplicationContext ctx1 = new AnnotationConfigApplicationContext();
// ctx1.register(DaoConfig.class); // 如果没有使用Import注解的话,一定要记得加上
ctx1.register(ServiceConfig.class);
ctx1.refresh();
LogonService logonService1 = ctx1.getBean(LogonService.class);
logonService1.printHello();


3.3 在XML配置中引用@Configuration配置,很简单,只需要<context:component-scan>可以扫描到即可。

3.4 在Configuration中引用XML配置信息,只需要在类上加上@ImportResource("classpath:com/firethewhole/conf/bean3.xml"),然后对应的每个方法都需要参数并且加上Autowired属性

@Configuration
@ImportResource("classpath:beans3.xml")
public class LogonAppConfig {
@Bean
@Autowired
public LogonService logonService(UserDao userDao, LogDao logDao) {
LogonService logonService = new LogonService();
logonService.setLogDao(logDao);
logonService.setUserDao(userDao);
return logonService;
}
}


<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.1.xsd">
<bean id="userDao" class="com.firethewhole.maventest05.dao.UserDao"/>
<bean id="logDao" class="com.firethewhole.maventest05.dao.LogDao"/>
</beans>
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值