目录
六、基于注解的 DI
6.1 使用方式
1. 加入 Maven 依赖,spring-context ,加入 spring-context 同时间接加入spring-aop依赖,使用注解必须使用 spring-aop 依赖。
<dependencies>
<dependency>
<groupId>junit</groupId>
<artifactId>junit</artifactId>
<version>4.11</version>
<scope>test</scope>
</dependency>
<!--spring依赖-->
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-contrxt</artifactId>
<version>5.2.5.RELEASE</version>
</dependency>
</dependencies>
2. 在类中加入 spring 的注解(多个不同功能的注解)
3. 在 spring 配置文件中,加入一个组件扫描器标签,说明注解在项目中的位置。
<?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 https://www.springframework.org/schema/context/spring-context.xsd">
<!--声明组件扫描器,组件就是java对象-->
<context:component-scan base-package="com.aojiaodeRR.DI01"/>
</beans>
<!--base-package = 指定注解在你的项目中的包名
component-scan工作方式 = spring 会扫描遍历 base-package指定的包,把包中的和子包中的所有类,找到类中的注解,按照注解的功能创建对象,或给属性赋值-->
6.2 七种主要注解
1. @component :创建对象,value = “对象名称” (value值不省略,并且可不指定对象名称,spring默认名称为首字母小写的类名)
java类:
package com.aojiaodeRR.DI01;
import org.springframework.stereotype.Component;
//value为对象名且唯一
@Component("mystudent")
public class Student {
private String name ;
private int age;
public Student() {
System.out.println("==========无参构造==========");
}
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;
}
@Override
public String toString() {
return "Student{" +
"name='" + name + '\'' +
", age=" + age +
'}';
}
}
配置文件:
<?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 https://www.springframework.org/schema/context/spring-context.xsd">
<!--声明组件扫描器,组件就是java对象-->
<context:component-scan base-package="com.aojiaodeRR.DI01"/>
</beans>
测试类:
package com.aojiaodeRR;
import com.aojiaodeRR.DI01.Student;
import org.junit.Test;
import org.springframework.context.ApplicationContext;
import org.springframework.context.support.ClassPathXmlApplicationContext;
public class Test01 {
@Test
public void test01(){
String Config = "DI01/applicationContext.xml";
ApplicationContext ac = new ClassPathXmlApplicationContext(Config);
Student student = (Student) ac.getBean("mystudent");
System.out.println(student);
}
}
测试结果:
2. @Respotory :放在dao实现类上,创建dao对象,用来连接访问数据库。
3. @Service :放在service实现类上面,创建service对象,做业务处理、事务处理。
4. @Controller :放在控制器类上,创建控制器对象,接受用户提交参数,显示请求处理结果。
(@Respotory 、@Service 、@Controller在用于给项目对象分层和@component 语法相同)
5. @Value :简单类型赋值,在属性上,无需set 、get方法。
Java类:
package com.aojiaodeRR.DI02;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.stereotype.Component;
//value为对象名且唯一
@Component("mystudent")
public class Student {
@Value("赵云")
private String name ;
@Value("22")
private int age;
public Student() {
System.out.println("==========无参构造==========");
}
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;
}
@Override
public String toString() {
return "Student{" +
"name='" + name + '\'' +
", age=" + age +
'}';
}
}
配置文件:
<?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 https://www.springframework.org/schema/context/spring-context.xsd">
<!--声明组件扫描器,组件就是java对象-->
<context:component-scan base-package="com.aojiaodeRR.DI02"/>
</beans>
测试文件:
package com.aojiaodeRR;
import com.aojiaodeRR.DI02.Student;
import org.junit.Test;
import org.springframework.context.ApplicationContext;
import org.springframework.context.support.ClassPathXmlApplicationContext;
public class Test02 {
@Test
public void test01(){
String Config = "DI02/applicationContext.xml";
ApplicationContext ac = new ClassPathXmlApplicationContext(Config);
Student student = (Student) ac.getBean("mystudent");
System.out.println(student);
}
}
测试结果:
6. @Autowired :引用类型赋值,自动注入。
注解写在属性定义上面,无需set、get方法,如果写在set方法上,默认byType。但也支持byName
需要在属性上加入 @Autowired,在属性上加入@qualifier(value = "beanID")
补充:required ,是一个Boolean类型,默认true。
required = true :表示引用类型赋值失败,终止。
required = false :执行但不报错,结果诶null。
Java类:
package com.aojiaodeRR.DI03;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.stereotype.Component;
@Component("myschool")
public class School {
@Value("哈尔滨理工大学")
private String name;
@Value("学府路")
private String place;
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public String getPlace() {
return place;
}
public void setPlace(String place) {
this.place = place;
}
@Override
public String toString() {
return "School{" +
"name='" + name + '\'' +
", place='" + place + '\'' +
'}';
}
}
package com.aojiaodeRR.DI03;
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;
//value为对象名且唯一
@Component("mystudent")
public class Student {
@Value("赵云")
private String name ;
@Value("22")
private int age;
@Autowired
@Qualifier(value = "myschool")
private School school;
public Student() {
System.out.println("==========无参构造==========");
}
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;
}
@Override
public String toString() {
return "Student{" +
"name='" + name + '\'' +
", age=" + age +
", school=" + school +
'}';
}
}
配置文件:
<?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 https://www.springframework.org/schema/context/spring-context.xsd">
<!--声明组件扫描器,组件就是java对象-->
<context:component-scan base-package="com.aojiaodeRR.DI03"/>
</beans>
测试类:
package com.aojiaodeRR;
import com.aojiaodeRR.DI03.Student;
import org.junit.Test;
import org.springframework.context.ApplicationContext;
import org.springframework.context.support.ClassPathXmlApplicationContext;
public class Test03 {
@Test
public void test01(){
String Config = "DI03/applicationContext.xml";
ApplicationContext ac = new ClassPathXmlApplicationContext(Config);
Student student = (Student) ac.getBean("mystudent");
System.out.println(student);
}
}
测试结果:
7. @Resource :JDK注解,引用类型赋值。自动注入(默认byName)支持byType,写在属性上,无需set、get方法。 先使用byName自动注入,失败再改用byType,只使用byName语法:@Resource(name = "ID")
Java类:
package com.aojiaodeRR.DI04;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.stereotype.Component;
@Component("myschool")
public class School {
@Value("哈尔滨理工大学")
private String name;
@Value("学府路")
private String place;
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public String getPlace() {
return place;
}
public void setPlace(String place) {
this.place = place;
}
@Override
public String toString() {
return "School{" +
"name='" + name + '\'' +
", place='" + place + '\'' +
'}';
}
}
package com.aojiaodeRR.DI04;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.stereotype.Component;
import javax.annotation.Resource;
//value为对象名且唯一
@Component("mystudent")
public class Student {
@Value("赵云")
private String name ;
@Value("22")
private int age;
@Resource(name = "myschool")
private School school;
public Student() {
System.out.println("==========无参构造==========");
}
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;
}
@Override
public String toString() {
return "Student{" +
"name='" + name + '\'' +
", age=" + age +
", school=" + school +
'}';
}
}
配置文件:
<?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 https://www.springframework.org/schema/context/spring-context.xsd">
<!--声明组件扫描器,组件就是java对象-->
<context:component-scan base-package="com.aojiaodeRR.DI04"/>
</beans>
测试类:
package com.aojiaodeRR;
import com.aojiaodeRR.DI04.Student;
import org.junit.Test;
import org.springframework.context.ApplicationContext;
import org.springframework.context.support.ClassPathXmlApplicationContext;
public class Test04 {
@Test
public void test01(){
String Config = "DI04/applicationContext.xml";
ApplicationContext ac = new ClassPathXmlApplicationContext(Config);
Student student = (Student) ac.getBean("mystudent");
System.out.println(student);
}
}
测试结果:
扩展:加载属性配置文件
<context:property-placeholder location ="classpath:名称">