Spring框架----->(3) 基于注解的DI(依赖注入)

一、基于注解的依赖注入

  1. 基于注解的di :通过注解完成java对象创建,属性赋值
  2. 使用注解的步骤

(1)加入maven的依赖 spring-context ,在你加入spring-context的同时, 间接加入spring-aop的依赖,使用注解必须使用spring-aop依赖

(2)在类中加入spring的注解(多个不同功能的注解)

(3)在spring的配置文件中,加入一个组件扫描器的标签,说明注解在你的项目中的位置

  1. 声明组件扫描器 : component-scan,组件就是对象

base-package:指定注解在项目中的包名
component-scan工作方式:spring会扫描遍历base-package指定的包,把包中和子包的所有类,找到类中的注解,按照注解的功能创建对象,或给属性赋值

  1. 指定多个包的三种方式
  • 第一种方式:使用多次组件扫描器,指定不同的包
<context:component-scan base-package="com.hcz.ba06"/>
<context:component-scan base-package="com.hcz.ba01"/>
<context:component-scan base-package="com.hcz.ba02"/>
  • 第二种方式:使用分隔符(‘’或者‘’)分割多个包名
<context:component-scan base-package="com.hcz.ba01;com.hcz.ba02"/>
  • 第三种方式:指定父包(不建议使用,因为扫描包时间过长)
<context:component-scan base-package="com.hcz"/>

(1)定义bean对象的注解@Component

解析
1、@Component : 创建对象的,等同于< bean/ >的功能
2、value属性: 就是对象的名称,也就是bean的id值,value的值是唯一的,创建对象在整个spring容器中就一个
3、位置:在类上面

等同代码:

@Component(value = "myStudent")等同于
<bean id="myStudent" class="com.hcz.ba01.Student1"></bean>

注意
spring中和@Component功能一致,创建对象的注解还有:
1、@Respotory(用在持久层类的上面):放在dao的实现类上面,
表示创建dao对象,dao对象是能访问数据库的
2、@Service(用在业务层类的上面):创建service对象,
service对象是做业务处理的,可以有事物等功能的
3、@Controller(用在控制器的上面):创建控制器对象,
它能够接收用户提交的参数,显示请求的处理结果
以上三个注解的使用语法和@Component一样的。都能创建对象,但是这三个注解是@Component的细化,他们还有额外的功能
4、@Respotory、@Service、@Controller是给项目的对象创建分层
5、什么时候使用@Component?
当以上三个都不满足时使用

  • 使用@Component的三种方式
  • (1)使用value属性指定对象的名称
@Component(value = "myStudent")
  • (2)省略value
@Component("myStudent")
  • (3)不使用对象名称,由spring提供默认名称(类名的首字母小写)
@Component
  • 创建实体类Student
@Component(value = "myStudent1")
public class Student1 {
    
    

    private String name;
    private Integer age;

    public Student1(){
    
    
        System.out.println("无参构造方法");
    }

    public void setName(String name) {
    
    
        this.name = name;
    }

    public void setAge(Integer age) {
    
    
        this.age = age;
    }

    @Override
    public String toString() {
    
    
        return "Student1{" +
                "name='" + name + '\'' +
                ", age=" + age +
                '}';
    }
}
  • spring配置文件
<context:component-scan base-package="com.hcz.ba01"/>
  • 测试方法
@Test
public void test01(){
    
    
    String config = "applicationContext.xml";
    ApplicationContext context = new ClassPathXmlApplicationContext(config);

    //获取对象
    Student1 student = (Student1) context.getBean("myStudent1");
    System.out.println("student="+student);
}

(2)简单类型属性注入@Value

解析
1、@value : 简单类型的属性赋值
2、属性 :value是String类型的,表示简单类型的属性值
3、位置
(1)在属性定义上面,无需set方法,推荐使用
(2)在set方法的上面

  • 使用@Value的两种方式
  • 1、直接在属性上面赋值
@Value(value = "李四")
private String name;
@Value(value = "33")
private Integer age;
  • 2、使用文档文件赋值
@Value("${name}")
private String name;
@Value("${age}")
private Integer age;

需要在resource目录下创建属性配置文件test.properties

name=张三
age=23

然后再在spring配置文件中加载属性配置文件

<!--加载属性配置文件-->
<context:property-placeholder location="test.properties"/>

(3)byType 自动注入@Autowired

解析
引用类型
@Autowired : spring框架提供的注解,实现引用类型的赋值。
spring中通过注解给引用类型赋值,使用的是自动注入原理,支持byName,byType
@Autowired : 默认的是byType自动注入

  • 创建实体类Student
@Component("myStudent")
public class Student {
    
    

    @Value(value = "李四")
    private String name;
    @Value(value = "33")
    private Integer age;
    @Autowired
    private School school;

    @Override
    public String toString() {
    
    
        return "Student1{" +
                "name='" + name + '\'' +
                ", age=" + age +
                ", school=" + school +
                '}';
    }
}
@Component("mySchool")
public class School {
    
    

    @Value("xx大学")
    private String name;
    @Value("xx市xx区")
    private String address;

    @Override
    public String toString() {
    
    
        return "School{" +
                "name='" + name + '\'' +
                ", address='" + address + '\'' +
                '}';
    }
}

解析
这里的School类注解注入也可以等价于xml配置文件注入,例如:

<bean id="mySchool" class="com.hcz.ba03.School">
         <property name="name" value="清华大学"/>
         <property name="address" value="北京市"/>
</bean>
  • Spring配置文件
<context:component-scan base-package="com.hcz.ba02"/>
  • 测试方法
@Test
public void test01(){
    
    
    String config = "applicationContext.xml";
    ApplicationContext context = new ClassPathXmlApplicationContext(config);

    //获取对象
    Student student = (Student) context.getBean("myStudent2");
    System.out.println("student="+student);
}

(4)byName 自动注入@Autowired 与@Qualifier

  • 需要在引用属性上联合使用注解@Autowired 与@Qualifier
  • 使用步骤:

如果要使用byName方式,需要做的是:
(1)在属性上面加入@Autowired
(2)在属性上面加入@Qualifier(value="bean的 id ")
例如:Student类中引用School类

@Autowired
@Qualifier("mySchool")
private School school;

注意
@Autowired 还有一个属性 required
1、required=true : 表示引用类型赋值失效,程序报错,并终止执行
2、required=false : 表示引用类型如果赋值失效,程序正常执行,引用类型是null

(5)JDK 注解@Resource 自动注入

Spring提供了对 jdk中@Resource注解的支持。@Resource 注解既可以按名称匹配Bean,也可以按类型匹配 Bean。但是默认是按名称注入。
例如:Student类中引用School类

1、byType 注入引用类型属性
@Resource
private School school;
@Component("mySchool")
public class School {
    
    

    @Value("xx学院")
    private String name;
    @Value("xx市")
    private String address;
}

解析
默认是byName:先使用byName自动注入,如果byName赋值失效,再使用byType
这里的类型都是School

2、byName 注入引用类型属性
@Resource(name = "mySchool")
private School school;
@Component("mySchool")
public class School {
    
    

    @Value("xx学院")
    private String name;
    @Value("xx市")
    private String address;
}

这里的名称都是 “mySchool”

(6)注解与 XML 的对比

  • 注解优点是:

⚫ 方便
⚫ 直观
⚫ 高效(代码少,没有配置文件的书写那么复杂)

  • 注解缺点是:

修改是需要重新编译代码的

  • XML 方式优点是:

⚫ 配置和代码是分离的
⚫ 在 xml 中做修改,无需编译代码,只需重启服务器即可将新的配置加载

  • XML 方式缺点是

编写麻烦,效率低,大型项目过于复杂

总结
需要经常修改使用xml注入,修改较少使用注解注入

猜你喜欢

转载自blog.csdn.net/hcz666/article/details/113307304