在Spring框架的应用中,可以为需要被Spring自动赋值的属性添加@Autowired
,则Spring框架会从Spring容器中找出匹配的值,并自动完成赋值!这就是Spring框架的自动装配机制!
当Spring尝试为某个属性实现自动装配时,采取的模式主要有:
byName
:根据名称实现自动装配,在这种模式下,要求被装配的属性名称,与被Spring管理的对象的名称(调用getBean()
方法给出的参数名)必须相同;byType
:根据类型实现自动装配,在这种模式,要求被装配的属性的类型,在Spring容器中存在匹配类型的对象,当应用这种机制时,必须在Spring容器中保证匹配类型的对象只有1个,否则,将会出现NoUniqueBeanDefinitionException
异常;
当使用@Autowired
尝试自动装配时,Spring框架会先根据byType
模式找出所有匹配类型的对象,如果匹配类型的对象的数量为0,也就是没有匹配类型的对象,默认情况下会直接报错,提示信息例如:
Caused by: org.springframework.beans.factory.NoSuchBeanDefinitionException:
No qualifying bean of type 'cn.tedu.spring.UserDao' available: expected at least 1
bean which qualifies as autowire candidate. Dependency annotations:
{@org.springframework.beans.factory.annotation.Autowired(required=true)}
如果使用
@Autowired
时明确的配置为@Autowired(required=false)
,当没有匹配类型的对象时,也不会因为装配失败而报错!
如果匹配类型的对象的数量为1,则直接装配;
如果匹配类型的对象的数量超过1个(有2个甚至更多个),会尝试byName
来装配,如果存在名称匹配的对象,则成功装配,如果名称均不匹配,则装配失败,会提示如下错误:
Caused by: org.springframework.beans.factory.
NoUniqueBeanDefinitionException:
No qualifying bean of type 'cn.tedu.spring.UserDao' available:
expected single matching bean but found 2:
userJdbcDao,userMybatisDao
当需要自动装配时,除了使用@Autowired
注解以外,还可以使用@Resource
注解!
当使用@Resource
注解尝试自动装配时,其工作原理是先尝试byName
装配,如果存在名称匹配的对象,则直接装配,如果没有名称匹配的对象,则尝试byType
装配。
另外,如果某个方法是被Spring调用的,还可以将需要装配的对象设置为方法的参数(不需要添加注解即可正常使用),Spring也可以实现方法参数的自动装配!例如:
public void test(UserDao userDao) {}
例子:
1.在src/main/resources下的配置文件:
db.url=jdbc:mysql://localhost:3306/db_name
db.driver=com.mysql.jdbc.Driver
db.username=root
db.password=1234
db.initialSize=5
2.jdbcConfig.java
package cn.tedu.spring;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.context.annotation.PropertySource;
import org.springframework.core.env.Environment;
import org.springframework.stereotype.Component;
@Component
@PropertySource("classpath:jdbc.properties")
public class JdbcConfig {
@Autowired
private Environment environment;
public Environment getEnvironment() {
return environment;
}
public void setEnvironment(Environment environment) {
this.environment = environment;
}
@Override
public String toString() {
return "JdbcConfig [environment=" + environment + "]";
}
}
3.SpringConfig.java
import org.springframework.context.annotation.ComponentScan;
@ComponentScan("cn.tedu.spring")
public class SpringConfig {
}
3.Demo.java
package cn.tedu.spring;
import org.springframework.context.annotation.AnnotationConfigApplicationContext;
import org.springframework.core.env.Environment;
public class Demo {
public static void main(String[] args) {
AnnotationConfigApplicationContext ac
= new AnnotationConfigApplicationContext(SpringConfig.class);
JdbcConfig jdbcConfig = ac.getBean("jdbcConfig", JdbcConfig.class);
Environment environment = jdbcConfig.getEnvironment();
System.out.println(environment.getProperty("db.url"));
System.out.println(environment.getProperty("db.driver"));
System.out.println(environment.getProperty("db.username"));
System.out.println(environment.getProperty("db.password"));
System.out.println(environment.getProperty("db.initialSize"));
ac.close();
}
}
4.测试结果: