3、Spring IOC的注解使用

1、概述

  上篇文章中整理了通过XML文件进行Bean或某些属性的赋值,xml的方式在企业开发中已经过时了,这篇文章即为进阶篇。介绍如何在bean上添加注解,快速的将bean注册到ioc容器。

2、使用注解的方式注册Bean到 IOC容器中

  如果想要将自定义的bean对象添加到IOC容器中,需要在类上添加某些注解 。

  Spring中包含4个主要的组件添加注解: 

  @Controller:控制器,推荐给controller层添加此注解

  @Service:业务逻辑,推荐给业务逻辑层添加此注解

  @Repository:仓库管理,推荐给数据访问层添加此注解

  @Component:给不属于以上基层的组件添加此注解

  注意:我们虽然人为的给不同的层添加不同的注解,但是在spring看来,可以在任意层添加任意注解。spring底层是不会给具体的层次验证注解,这样写的目的只是为了提高可读性,最偷懒的方式就是给所有想交由IOC容器管理的bean对象添加component注解

  使用注解需要如下步骤:

  1、添加上述四个注解中的任意一个

  2、添加自动扫描注解的组件,此操作需要依赖context命名空间

  3、添加自动扫描的标签context:component‐scan

  注意:当使用注解注册组件和使用配置文件注册组件是一样的,但是要注意:

  1、组件的id默认就是组件的类名首字符小写,如果非要改名字的话,直接在注解中添加即可。如 @Controller("userInfo")

  2、组件默认情况下都是单例的,如果需要配置多例模式的话,可以在注解下添加@Scope注解

  <!-- 定义自动扫描的基础包:
    base‐package:指定扫描的基础包,spring在启动的时候会将基础包及子包下所有加了注解的类都自动扫描进IOC容器-->
    <context:component-scan base-package="com.zhl"></context:component-scan>
package com.zhl.controller;

import org.springframework.stereotype.Controller;

@Controller
public class UserController {
}
package com.zhl.service;

import org.springframework.stereotype.Service;

@Service
public class UserService {
}
package com.zhl.dao;

import org.springframework.stereotype.Repository;

@Repository
public class UserDao {
}

 3、定义扫描包时要包含的类和不要包含的类

  当定义好基础的扫描包后,在某些情况下可能要有选择性的配置是否要注册bean到IOC容器中,此时可以通过如下的方式进行配置。

  <!-- 定义自动扫描的基础包:
    base‐package:指定扫描的基础包,spring在启动的时候会将基础包及子包下所有加了注
    解的类都自动扫描进IOC容器-->
    <context:component-scan base-package="com.zhl.entity" use-default-filters="false">
        <!--当定义好基础扫描的包之后,可以排除包中的某些类,使用如下的方式:
         type:表示指定过滤的规则
            annotation:按照注解进行排除,标注了指定注解的组件不要,expression表示要过滤的注解的全限定类名,该注解下的Bean全部排除
            assignable:指定排除某个具体的类,按照类排除,expression表示不注册的具体类名-->
       <!-- <context:exclude-filter type="annotation" expression="org.springframework.stereotype.Controller"/>-->
        <!--<context:exclude-filter type="assignable" expression="com.zhl.entity.User"/>  -->

        <!--指定只扫描哪些组件,默认情况下是全部扫描的,所以此时要配置的话需要在component‐scan标签中添加 use‐default‐filters="false"-->
        <!--<context:include-filter type="annotation" expression="org.springframework.stereotype.Controller"/>-->
        <context:include-filter type="assignable" expression="com.zhl.entity.User"/>
    </context:component-scan>

 4、使用@AutoWired进行自动注入

  使用注解的方式实现自动注入,需要使用@AutoWired注解。

  注意:当使用AutoWired注解的时候,自动装配的时候是根据类型实现的。

    a、如果只找到一个,则直接进行赋值,

    b、如果没有找到,则直接抛出异常,

    c、如果找到多个,那么会按照变量名作为id继续匹配,

      c.1、匹配上直接进行装配

      c.2、如果匹配不上则直接报异常

package com.zhl.controller;

import com.zhl.service.UserService;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Controller;

@Controller
public class UserController {
    /*
    使用@Autowired来实现自动注入
    bytype?  byname?
    ·默认优先根据类型去匹配
    ·如果匹配到多个类型则会按照名字匹配
    ·如果名又没有匹配到则会报错:
                    1.可以去修改属性的名字对应bean的名字:userServiceImpl
                    2.可以去修改Bean的名字对应属性的名字:@Service("userService")
                    3.可以通过@Qualifier设置属性的名字(覆盖) :@Qualifier("userServiceImpl")
                    4.可以通过@Primary 设置其中一个Bean为主要的自动注入Bean:@Primary
                    5.使用泛型作为自动注入限定符
     */
    @Autowired
    private UserService userService;

    public void getUser() {
        userService.getUser();
    }
} 
package com.zhl.service;

import org.springframework.stereotype.Service;

@Service
public class UserService {

    public void getUser() {
        System.out.println("返回User");
    }
}

5、@AutoWired可以进行定义在方法上

  此注解不仅可以使 用在成员变量上,也可以使用在方法上。

 

package com.zhl.controller;

import com.zhl.service.UserService;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Controller;

@Controller
public class UserController {
    /*
    使用@Autowired来实现自动注入
    bytype?  byname?
    ·默认优先根据类型去匹配
    ·如果匹配到多个类型则会按照名字匹配
    ·如果名又没有匹配到则会报错:
                    1.可以去修改属性的名字对应bean的名字:userServiceImpl
                    2.可以去修改Bean的名字对应属性的名字:@Service("userService")
                    3.可以通过@Qualifier设置属性的名字(覆盖) :@Qualifier("userServiceImpl")
                    4.可以通过@Primary 设置其中一个Bean为主要的自动注入Bean:@Primary
                    5.使用泛型作为自动注入限定符
     */
    @Autowired
    private UserService userService;

    public void getUser() {
        userService.getUser();
    }


    /**
     * @Autowired 也可以写在构造器上面
     * ·默认优先根据参数类型去匹配
     * ·如果匹配到多个类型则会按照参数名字匹配
     */
     @Autowired
     public UserController(UserService userService) {
     this.userService = userService;
     }

    /**
     * @Autowired 也可以写在方法上面
     * ·默认优先根据参数类型去匹配
     * ·如果匹配到多个类型则会按照参数名字匹配
     * @param userService
     * 当方法上有@AutoWired注解时:
     * 1、此方法在bean创建的时候会自动调用
     * 2、这个方法的每一个参数都会自动注入值
     */
     @Autowired
     public void createUserSerive(UserService userService){
        this.userService=userService;
     }
}

6、自动装配的注解@AutoWired,@Resource

  在使用自动装配的时候,除了可以使用@AutoWired注解之外,还可以使用@Resource注解,区别如下:

  a、@AutoWired:是spring中提供的注解,@Resource:是jdk中定义的 注解,依靠的是java的标准

  b、@AutoWired默认是按照类型进行装配,默认情况下要求依赖的对象必须存在,@Resource默认是按照名字进行匹配的,同时可以指定name属性。

  c、@AutoWired只适合spring框架,而@Resource扩展性更好

  d、@Autowired如果需要按照名称匹配需要和@Qualifier一起使用

 

posted @ 2021-10-23 14:13  一右四分之一  阅读(40)  评论(0编辑  收藏  举报