2.2、基于注解的DI注入

学习资源:动力节点的2020最新Spring框架教程【IDEA版】-Spring框架从入门到精通


基于注解的 DI,是指通过 Spring 提供的注解完成容器对象的创建、属性初始化,而不再需要使用配置文件声明创建 bean 了。

注解使用步骤:

  1. 导入 maven 依赖 spring-context
  2. 在实体类加入注解
  3. 在 spring 配置文件中,配置组件扫描器,用于指定扫描哪些包下的注解

Spring 常用注解:

  • @Component
  • @Respotory
  • @Service
  • @Controller
  • @scope
  • @Value
  • @Autowire
  • @Resource

0、准备工作

0.1、导入 maven 依赖

<dependency>
    <groupId>org.springframework</groupId>
    <artifactId>spring-context</artifactId>
    <version>5.2.5.RELEASE</version>
</dependency>

0.2、创建实体类


0.3、配置组件扫描器

组件扫描器的工作方式:spring 会扫描逼历 base-package 指定的包及子包中所有的类,找到类中的注解,按照注解的功能创建对象或给属性赋值。

配置组件扫描器,在配置文件中加入:

<context:component-scan base-package="com.chen.pojo"/>

指定扫描多个包的方式:

  1. 使用多次组件扫描器,扫描不同的包
<context:component-scan base-package="com.chen.pojo"/>
<context:component-scan base-package="com.chen.domain"/>
......
  1. 使用分隔符 ; 或 , 分割多个包
<context:component-scan base-package="com.chen.pojo;com.chen.domain;......"/>
  1. 指定父包
<context:component-scan base-package="com.chen"/>

1、@Component

作用等同于配置文件中的 <bean> ,用于向容器中创建对象。需要在实体类上使用注解 @Component ,该注解的 value 属性用于指定该 bean 的 id 值,id 自定义唯一,value 属性可缺省。

使用实例:

  1. @Component(value="自定义名称")
@Component(value="student")
public class Student{
    
}
  1. @Component("自定义名称"),推荐使用
@Component(value="student")
public class Student{
    
}
  1. @Component(),此时 bean 会使用 spring 提供的默认名称:类名首字母小写
@Component()
public class Student{
    
}

另外, Spring 还提供了 3 个创建对象的注解:

  • @Repository:用于对持久层类(DAO 实现类)进行注解
  • @Service:用于对业务层类(Service 实现类)进行注解
  • @Controller:用于对控制器类(Controller 实现类)进行注解

这三个注解与 @Component 都可以创建对象,但这三个注解还有其他的含义:@Repository 创建持久层对象,持久层对象是可以操作数据库的;@Service 创建业务层对象,业务层对象可以加入事务功能;@Controller 注解创建的对象可以作为处理器接收用户的请求。

@Repository、@Service、@Controller 是用于给项目的对象分层的:持久层、业务层、控制层。而当你不确定某一个对象的角色时,可以使用 @Component 。


2、@Value

功能等同于 <\property name="" value=""> ,用于给简单类型的属性赋值。

需要在属性上使用注解@Value,该注解的 value 属性用于指定要注入的值。使用该注解完成属性注入时,类中无需 setter。当然,若属性有 setter,则也可将其加到 setter 上。

使用实例:

  1. 在属性定义的上面使用,无需 setter ,推荐使用
@Componnet("student")
public class Student{
    
    // @Value(value = "张san"),value属性可不写
    @Value("张san")
    private String name;
    @Value("29")
    private int age;
}
  1. 在 setter 上使用
@Componnet("student")
public class Student{
    
    private String name;
    private int age;
    
    @Value("张三")
    public void setName(String name) {
        this.name = name;
    }
	@Value("29")
    public void setAge(String age) {
        this.age = age;
    }
}

3、@Scope

功能同 <\bean> 的scop 属性相同,在实体类上使用,用于设置 bean 的作用域。

  • @Scope("singleton"):单例
  • @Scope("prototype"):多例

4、@Atuowired(不推荐使用了)

功能与 <bean ... autowire=""> 相同,用于为引用类型的属性赋值。@Atuowired 默认使用的是 byType 自动从容器中装配 Bean。

4.1、byType

byType 是 @Atuowired 的默认方式,直接在属性上使用,类中无需 setter。若属性有 setter,也可将其加到 setter 上。推荐直接在属性上使用。

使用实例:

@Component("student")
public class Student {
    
    @Value("16")
    private int age;
    @Autowired
    private School school;
}

///////////////////////////////////////////////////////////////////////

@Component("school")
public class School {
    
    @Value("3000")
    private int area;
}

4.2、byName

需要再借助另一个注解 @Qualifier("容器中 bean 的 id"),才可以更改 @Atuowired 的自动装配方式。

@Autowirted
@Qualifier(value="容器中bean的id")

使用实例:

@Component("student")
public class Student {
    
    @Value("16")
    private int age;
    
    @Autowired
    @Qualifier("stuSchool")
    private School school;
}

///////////////////////////////////////////////////////////////////////

@Component("stuSchool")
public class School {
    
    @Value("3000")
    private int area;
}

3.3、required

required 是 @Autowired 的一个属性,默认值为 true。建议使用 true

  • true 表示如果引用类型赋值失败,程序报错终止执行
  • false 表示如果引用类型赋值失败,程序正常执行,引用类型赋为 null、
@Component("student")
public class Student {
    
    @Value("16")
    private int age;
    
    @Autowired(required=true)
    private School school;
}

4、@Resource

@Resource 是 JDK 的注解,Spring 提供了对它的支持。

同 @Atuowired 一样,@Resource 也是既可以 byType,也可以 byName,默认是 byName。

@Resource 可用在属性上,也可以用在 setter 上,推荐直接用在属性上。


4.1、byType

@Resource 注解若不带任何参数, 采用默认 byName 的方式注入,若 byName 失败,则转而使用 byType。

使用实例:

@Component("student")
public class Student {
    
    @Value("16")
    private int age;
    
    @Resource
    private School school;
}

///////////////////////////////////////////////////////////////////////

@Component("stuSchool")
public class School {
    
    @Value("3000")
    private int area;
}

4.2、byName

@Resource 注解指定其 name 属性的值,则 name 的值即为按照名称进行匹配的 Bean 的 id。

@Component("student")
public class Student {
    
    @Value("16")
    private int age;
    
    @Resource(name="stuSchool")
    private School school;
}

///////////////////////////////////////////////////////////////////////

@Component("stuSchool")
public class School {
    
    @Value("3000")
    private int area;
}

5、注解与XML对比

注解的优点:

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

注解的缺点:

  • 以硬编码的方式写入到 Java 代码中,修改是需要重新编译代码的

XML 方式优点是:

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

缺点:

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

最佳实践:注解为主,配置文件为辅

posted @ 2020-09-06 17:11  卡文迪雨  阅读(209)  评论(0编辑  收藏  举报