极速版
- src/step4/StudentImpl.java
-
package step4; import org.springframework.beans.factory.annotation.Value; import org.springframework.stereotype.Component; @Component("student") public class StudentImpl implements Student { @Value("小明") private String name; @Value("20") private int age; @Override public String toString() { return "Student [name=" + name + ", age=" + age + "]"; } }
- src/step4/Teacher.java
-
package step4; import javax.annotation.Resource; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.beans.factory.annotation.Qualifier; import org.springframework.beans.factory.annotation.Value; import org.springframework.stereotype.Component; @Component("teacher") public class Teacher { @Value("张老师") private String name; @Autowired private Student student; @Override public String toString() { return "Teacher [name=" + name + ", student=" + student + "]"; } }
- src/step4/applicationContext4.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" xmlns:context="http://www.springframework.org/schema/context" xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans.xsd http://www.springframework.org/schema/context http://www.springframework.org/schema/context/spring-context.xsd"> <!-- 配置包扫描器开始 --> <context:component-scan base-package="step4"></context:component-scan> <!-- 配置包扫描器结束 --> </beans>
- src/step4/Test.java
-
package step4; import org.springframework.context.ApplicationContext; import org.springframework.context.support.ClassPathXmlApplicationContext; public class Test { public static void main(String[] args) { /********** Begin **********/ //使用ApplicationContext容器获取对象 ApplicationContext applicationContext=new ClassPathXmlApplicationContext("applicationContext4.xml"); Teacher teacher=(Teacher) applicationContext.getBean("teacher"); //打印对象 System.out.println(teacher); // System.out.println("Teacher [name=张老师, student=Student [name=小明, age=20]] "); /********** End **********/ } }
以下题目:
任务描述
本关任务:利用注解注入获取对象。
相关知识
第二节和第三节介绍的两种方法都要在 java 代码里写方法来实现依赖注入,这样非常麻烦,为了解决这个问题,注解注入应用而生,不再需要写方法来实现,而是通过注解即可。
为了完成本关任务,你需要掌握:怎样使用注解注入。
课程视频 - Spring 注解
配置包扫描器
使用注解前,我们需要配置包扫描器,他会自动在 classpath 下扫描,侦测和实例化具有特定注解的组件。特定组件包括:
@Component: 基本注解,标识了一个受 Spring 管理的组件
@Repository: 标识持久层组件
@Service: 标识服务层(业务层)组件
@Controller: 标识表现层组件
对于扫描到的组件, Spring 有默认的命名策略,使用非限定类名,第一个字母小写,也可以在注解中通过 value 属性值标识组件的名称。当在组件类上使用了特定的注解后,还需要在 Spring 的配置文件中声明 <context:component-scan>:
base-package 属性指一个需要扫描的基类包,Spring 容器将会扫描这个基类包里及其子包中的所有类。
当需要扫描多个包时,可以使用逗号分隔。
如果仅希望扫描特定的类,可使用 resource-pattern 属性过滤特定的类。
示例:
具体代码如下:
<beans xmlns="http://www.springframework.org/schema/beans"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xmlns:context="http://www.springframework.org/schema/context"
xsi:schemaLocation="http://www.springframework.org/schema/beans
http://www.springframework.org/schema/beans/spring-beans.xsd
http://www.springframework.org/schema/context
http://www.springframework.org/schema/context/spring-context.xsd">
<!-- 配置包扫描器 -->
</beans>
基于注解配置 Bean
在配置完包扫描器后,我们开始使用注解:
@Component("student")
public class Student {
//属性省略
}
//指定 @Component 中的 value 即可在测试类中的 getBean()中植入即可。
public class Test {
public static void main(String[] args) {
ApplicationContext applicationContext=new ClassPathXmlApplicationContext("applicationContext.xml");
Student stu=(Student) applicationContext.getBean("student");
System.out.println(stu);
}
}
基于注解装配 Bean 的属性
bean 的属性可以使用注解的 @Value 来进行配置:
@Component("student")
public class Student {
@Value("小明")
private String name;
}
基于注解配置 Bean 与 Bean 之间的关系
@Autowired 顾名思义,就是自动装配,其作用是为了消除代码 Java 代码里面的 setter 方法与 bean 中的 property 属性。
示例:
@Component("teacher")
public class Teacher {
@Autowired
private Student student;
}
@Component("student")
public class Student {
}
如果是一个接口,且实现类有多个,还需要添加 @Qualifier(value) 进行指定,或是直接使用 @Resource 指定。
示例:
public interface Car{
public String carName();
}
@Service("bmw")
public class BMW implements Car{
public String carName(){
return "BMW car";
}
}
@Service("benz")
public class Benz implements Car{
public String carName(){
return "Benz car";
}
}
@Service("carFactory")
public class CarFactory{
@Autowired
private Car car;
}
此时去获取 CarFactory 程序会报错, Car 接口有两个实现类, Spring 并不知道应当引用哪个实现类,所以此时需修改:
@Service("carFactory")
public class CarFactory{
/*@Autowired
@Qualifier("bmw")*/
@Resource(name = "bmw")
private Car car;
}
指通使用类之后,输出:
BMW car
编程要求
查看右侧文件夹,完成以下任务:
在 Student 接口的实现类 StudentImpl 类和 Teacher 类中配置好相应的注解;
将 Spring 的配置文件applicationContext4.xml补充完整,注意配置 context 标签;
在 Test 类中获取并打印 Teacher 对象。
测试说明
平台会对你编写的代码进行测试:
预期输出:
Teacher [name=张老师, student=Student [name=小明, age=20]]