目录
任务描述
相关知识
编程要求
测试说明
参考答案
本关任务:利用注解注入获取对象。
第二节和第三节介绍的两种方法都要在java
代码里写方法来实现依赖注入,这样非常麻烦,为了解决这个问题,注解注入应用而生,不再需要写方法来实现,而是通过注解即可。
为了完成本关任务,你需要掌握:怎样使用注解注入。
配置包扫描器
使用注解前,我们需要配置包扫描器,他会自动在classpath
下扫描,侦测和实例化具有特定注解的组件。特定组件包括:
@Component:基本注解,标识了一个受Spring管理的组件
@Repository:标识持久层组件
@Service:标识服务层(业务层)组件
@Controller:标识表现层组件
对于扫描到的组件,Spring
有默认的命名策略,使用非限定类名,第一个字母小写,也可以在注解中通过value
属性值标识组件的名称。当在组件类上使用了特定的注解后,还需要在Spring
的配置文件中声明
:
base-package
属性指一个需要扫描的基类包,Spring
容器将会扫描这个基类包里及其子包中的所有类。
当需要扫描多个包时,可以使用逗号分隔。
如果仅希望扫描特定的类,可使用resource-pattern
属性过滤特定的类。
示例:
具体代码如下:
基于注解配置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]]
开始你的任务吧,祝你成功!
StudentImpl.java
package step4;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.stereotype.Component;
@Component("studentImpl")
public class StudentImpl implements Student {
@Value("小明")
private String name;
@Value("20")
private int age;
@Override
public String toString() {
return "Student [name=" + name + ", age=" + age + "]";
}
}
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 + "]";
}
}
applicationContext4.xml
Test.java
package step4;
import org.springframework.context.ApplicationContext;
import org.springframework.context.support.ClassPathXmlApplicationContext;
public class Test {
public static void main(String[] args) {
//使用ApplicationContext容器获取对象
ApplicationContext app = new ClassPathXmlApplicationContext("applicationContext4.xml");
Teacher t = app.getBean("teacher",Teacher.class);
//打印对象
System.out.println(t.toString());
}
}