Spring4笔记5--基于注解的DI(依赖注入)

基于注解的DI(依赖注入):

  对于 DI 使用注解,将不再需要在 Spring 配置文件中声明 Bean 实例。只需要在 Spring 配置文件中配置组件扫描器,用于在指定的基本包中扫描注解。

 1 <?xml version="1.0" encoding="UTF-8"?>
 2 <beans xmlns="http://www.springframework.org/schema/beans"
 3     xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
 4     xmlns:context="http://www.springframework.org/schema/context" xsi:schemaLocation="
 5         http://www.springframework.org/schema/beans 
 6         http://www.springframework.org/schema/beans/spring-beans.xsd
 7         http://www.springframework.org/schema/context 
 8         http://www.springframework.org/schema/context/spring-context.xsd">    
 9     <!-- 只扫描子包,不扫描当前包 -->
10     <!--  <context:component-scan base-package="com.tongji.*"/>  -->
11     <!-- 先扫描子包,再扫描当前包 -->
12     <!--  <context:component-scan base-package="com.tongji"/>  -->
13     
14     <context:component-scan base-package="com.tongji.di01"/>
15 </beans>

    注意:添加的约束http://www.springframework.org/schema/context/spring-context.xsd

  注解基本注入:

 1 package com.tongji.di01;
 2 
 3 import org.springframework.beans.factory.annotation.Value;
 4 import org.springframework.context.annotation.Scope;
 5 import org.springframework.stereotype.Component;
 6 
 7 //与本注解具有相同功能的注解还有三个:
 8 //@Repository:注解在Dao接口的实现类上,表示当前Dao类为组件
 9 //@Service:注解在Service接口的实现类上,表示当前Service类为组件
10 //@Controller:注解在Controller接口的实现类上,表示当前Controller类为组件(SpringMVC)
11 @Component("student")  //表明当前类为组件,容器创建的这个组件对象名称为myStudent,相当于<bean/>的id属性
12 @Scope("prototype") //设置Bean的作用范围,默认是singleton
13 public class Student {
14     @Value("张三")  //为name属性赋值
15     private String name;
16     private int age;
17     
18     public String getName() {
19         return name;
20     }
21     
22     public void setName(String name) {
23         System.out.println("执行setName");
24         this.name = name;
25     }
26     
27     public int getAge() {
28         return age;
29     }
30     
31     @Value("23")  //可以将该注解放到set上
32     public void setAge(int age) {
33         this.age = age;
34     }
35 
36     @Override
37     public String toString() {
38         return "Student [name=" + name + ", age=" + age + "]";
39     }
40     
41 }

    解释:注解注入时,POJO类可以没有setXXX()方法,但还是写上去比较好。

  

  注解域属性的自动注入:

    (1) 用Spring自带的注解实现:  

1 @Component("myStudent") 
2 @Scope("prototype") 
3 public class Student {
4     @Value("张三") 
5     private String name;
6     @Value("23")  
7     private int age;
8     @Autowired  //byType方式自动注入
9     private School school;
 1 @Component("myStudent") 
 2 @Scope("prototype") 
 3 public class Student {
 4     @Value("张三") 
 5     private String name;
 6     @Value("23")  
 7     private int age;
 8     @Autowired
 9     @Qualifier("mySchool")  //byName方式自动注入
10     private School school;

    补充:@Autowired 还有一个属性 required,默认值为 true,表示当匹配失败后,会终止程序运行。若将其值设置为 false,则匹配失败,将被忽略,未匹配的属性值为 null。

    (2)使用JDK提供的注解实现:

1 @Component("myStudent") 
2 @Scope("prototype") 
3 public class Student {
4     @Value("张三") 
5     private String name;
6     @Value("23")  
7     private int age;
8     @Resource  //byType方式自动注入
9     private School school;
1 @Component("myStudent") 
2 @Scope("prototype") 
3 public class Student {
4     @Value("张三") 
5     private String name;
6     @Value("23")  
7     private int age;
8     @Resource(name="mySchool")  //byName方式自动注入
9     private School school;

  注解Bean的定制声明始末:

1     @PostConstruct
2     public void postInit() {
3         System.out.println("初始化完毕之后");
4     }
5     
6     @PreDestroy
7     public void preDestory() {
8         System.out.println("销毁之前");
9     }

    在方法上使用@PostConstruct,与原来的 init-method 等效。在方法上使用@PreDestroy,与 destroy-method 等效。  

  使用JavaConfig进行配置:

    JavaConfig,是在 Spring 3.0 开始从一个独立的项目并入到 Spring 中的。JavaConfig 可以看成一个用于完成 Bean 装配的配置文件,只不过是程序员使用 Java 自己编写的。  

 1 package com.tongji.di07;
 2 
 3 import org.springframework.beans.factory.annotation.Autowire;
 4 import org.springframework.context.annotation.Bean;
 5 import org.springframework.context.annotation.Configuration;
 6 
 7 @Configuration  //表明当前POJO类将会被当作配置文件来使用,即Spring容器
 8 public class MyJavaConfig {
 9     
10     @Bean(name="mySchool")     //表明当前方法的返回值为一个Bean对象
11     public School mySchoolCreater() {
12         return new School("清华大学");
13     }
14     
15     @Bean(name="school")     //byName方式需要定义的该Bean的name值与被注入的属性名相同
16     public School mySchoolCreater2() {
17         return new School("北京大学");
18     }
19     
20     //@Bean(name="myStudent", autowire=Autowire.BY_TYPE)     //byType方式自动注入
21     @Bean(name="myStudent", autowire=Autowire.BY_NAME)       //byName方式自动注入
22     public Student myStudentCreater() {
23         return new Student("赵六",26);
24     }
25 }

    解释:此时School类和Student类就不需要注解了。

  使用 junit4 测试 Spring:

    对 Spring 程序的运行,首先需要创建容器对象,而后还要从容器中获取对象,再对其进行执行。但,JUnit4 对 Spring 程序有专门的测试方法。

 1 package com.tongji.di08;
 2 
 3 import org.junit.Test;
 4 import org.junit.runner.RunWith;
 5 import org.springframework.beans.factory.annotation.Autowired;
 6 import org.springframework.beans.factory.annotation.Qualifier;
 7 import org.springframework.test.context.ContextConfiguration;
 8 import org.springframework.test.context.junit4.AbstractJUnit4SpringContextTests;
 9 import org.springframework.test.context.junit4.SpringJUnit4ClassRunner;
10 
11 //使用Spring的测试
12 @RunWith(SpringJUnit4ClassRunner.class)
13 @ContextConfiguration(locations="classpath:com/tongji/di08/applicationContext.xml")
14 public class MyTest2 extends AbstractJUnit4SpringContextTests {
15     
16     @Autowired              //byType
17     @Qualifier("myStudent")  //byName
18     private Student student;
19     @Test
20     public void test01() {
21         System.out.println(student);
22     }
23     
24 }

    注意:Student对象的注入方式可以是基于XML的,也可以是基于注解的。

  注解与XML共同使用:

    注解的好处是,配置方便,直观。但其弊端也显而易见:以硬编码的方式写入到了 Java代码中,其修改是需要重新编译代码的。  
    XML 配置方式的最大好处是,对其所做修改,无需编译代码,只需重启服务器即可将新的配置加载。  
    若注解与 XML 同用,XML 的优先级要高于注解。这样做的好处是,需要对某个 Bean做修改,只需修改配置文件即可。当然,此时,Bean 类要有 setXXX() 或构造器。

原文地址:https://www.cnblogs.com/qjjazry/p/6362754.html