目录
Spring源码深度解析,Spring源码以及组件(六)(附代码示例:Cap9)
一,@Value,即一般都是给 类的 属性 赋值
二,@Autowired ,即自动装配, spring 利用依赖注入(Di) 完成对IOC容器中的各个组件的依赖关系赋值,并且对 bean 的 加载优先级做处理,
2.1,@Qualifier, 指定装配组件id 进行加载
2.2,@Primary,优先加载指定Bean
三,@Resource(JSR250), 即自动装配
3.1, @Resource 和 @Autowired 一样都可以装配bean。 缺点:不能支持 @Primary功能,@Autowired(requied = false ) 的功能 。
四,@Inject(JSR330), 即自动装配,
4.1,@inject 与 @Autowired 一样可以装配 Bean ,并支持 @Primary功能,可用于非Spring 框架。 缺点: 不能支持 @Autowired(requied = false ) 的功能, 需要引入第三方包 javax.inject
五,项目Demo地址
sex 这个属性, 是通过 properties 文件注入的。 @PropertySource 会把文件去交给 Spring 去扫描,去注入到容器,会加载到 Spring 里面有个类, 环境变量中。
ConfigurableEnvironment environment = applicationContext.getEnvironment();
通过从环境变量中直接取到 user.sex 的值
environment.getProperty("user.sex")
@PropertySource(value = {"classpath:/test.properties"})
@Configuration
public class Cap9MainConfig {
@Bean
public User user(){
return new User();
}
}
properties 文件:
user.sex = 22
自定义 User 类: 通过 注解 @Value 赋值 初始化 属性。
public class User {
@Value("张三")
private String name;
@Value("30")
private int age;
@Value("${user.sex}")
private String sex;
public User() {
}
public User(String name, int age,String sex) {
super();
this.name = name;
this.age = age;
this.sex = sex;
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public int getAge() {
return age;
}
public void setAge(int age) {
this.age = age;
}
public String getSex() {
return sex;
}
public void setSex(String sex) {
this.sex = sex;
}
@Override
public String toString() {
return "User{" +
"name='" + name + '\'' +
", age=" + age + '\'' +
", sex=" + sex +
'}';
}
}
测试:
@Test
public void test(){
//将配置类添加到容器中
AnnotationConfigApplicationContext applicationContext = new AnnotationConfigApplicationContext(Cap9MainConfig.class);
User user = (User) applicationContext.getBean("user");
System.out.println(user);
//properties 会加载到环境变量中,那么可以从环境变量里直接取 user.sex 的值
ConfigurableEnvironment environment = applicationContext.getEnvironment();
System.out.println("environment=====>" + environment.getProperty("user.sex"));
//关闭容器
applicationContext.close();
}
声明一个 UserDao
public class UserDao {
@Value("1")
private String flag;
public UserDao() {
}
public String getFlag() {
return flag;
}
public void setFlag(String flag) {
this.flag = flag;
}
@Override
public String toString() {
return "UserDao{" +
"flag='" + flag + '\'' +
'}';
}
}
声明一个 业务类。。 使用 注解 @Auto wired 装配到容器中,这里有一个地方,需要注意一下 required 这个属性
下面是 @Autowired 注解 源码,
也就是说, 在我们使用@Autowired 注解装配 bean 的时候, @Autowired 源码 required 属性默认为 ture, 也就是说 Spring 容器中必须存在 @Autowired 注解 准备 装配的 Bean, 当然 required 属性 也可以设置为 false ,就是忽略。
注①: 如果你没有注册 Bean , 而去 使用 类似@Autowired 注解 去装配,会出现下面的异常:
Exception encountered during context initialization - cancelling refresh attempt: org.springframework.beans.factory.UnsatisfiedDependencyException: Error creating bean with name 'userService': Unsatisfied dependency expressed through field 'userDao'; nested exception is org.springframework.beans.factory.NoSuchBeanDefinitionException: No qualifying bean of type 'com.enjoy.Cap9.Dao.UserDao' available: expected at least 1 bean which qualifies as autowire candidate. Dependency annotations: {@org.springframework.beans.factory.annotation.Autowired(required=true)}
org.springframework.beans.factory.UnsatisfiedDependencyException: Error creating bean with name 'userService': Unsatisfied dependency expressed through field 'userDao'; nested exception is org.springframework.beans.factory.NoSuchBeanDefinitionException: No qualifying bean of type 'com.enjoy.Cap9.Dao.UserDao' available: expected at least 1 bean which qualifies as autowire candidate. Dependency annotations: {@org.springframework.beans.factory.annotation.Autowired(required=true)}
注②:如果你忘记注册, 而 使用 @Autowired (required =false) 装配的时候忽略没有注册到容器的bean, 打印出来的 Bean 实例 会是 null 没有实例化的, 也不会出现什么异常。
这也是 @Autowired 与 @ Recource 注解 区别 之一。 @Recource 是容器必须有注册了Bean, 没有属性 设置。没有就抛异常
@Service
public class UserService {
@Autowired(required = false)
private UserDao userDao;
/**
* 测试是否已经自动装配
*/
public void println() {
System.out.println(userDao);
}
}
以下是配置类:
@ComponentScan({"com.enjoy.Cap9.*"}) //扫描Cap9,下面所有的包
public class Cap9Main2Config {
@Bean
public UserDao userDao(){
return new UserDao();
}
}
Spring源码深度解析,(附代码示例 码云地址: https://gitee.com/Crazycw/SpringCode.git)
参考资料: https://docs.spring.io/spring/docs/4.3.18.BUILD-SNAPSHOT/spring-framework-reference/htmlsingle/
请看下篇: Spring源码深度解析,Spring核心技术 Aop,详解 Aop(七)(附代码示例:)
https://blog.csdn.net/Crazy_Cw/article/details/93771602