Spring IOC注解的使用

1、使用注解的方式注册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默认就是组件的类名首字符小写,如果非要改名字的话,直接在注解中添加即可
  2、组件默认情况下都是单例的,如果需要配置多例模式的话,可以在注解下添加@Scope注解

  

  配置文件:applicationContext.xml

<?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
        http://www.springframework.org/schema/context/spring-context.xsd">
    <!--定义自动扫描的基础包:
      base-package:指定扫描的基础包,spring在启动的时候会将基础包及子包下所有加了注解的类都自动扫描进IOC容器
    -->
    <context:component-scan base-package="com.llxazy"></context:component-scan>
</beans>

 

//控制器 PersonController.java

package com.llxazy.controller;

import org.springframework.stereotype.Controller;

@Controller
public class PersonController {
    public PersonController() {
        System.out.println("创建对象");
    }
}


//业务逻辑 PersonService.java

package com.llxazy.service;

import org.springframework.stereotype.Service;

@Service
public class PersonService {
}

//仓库管理 PersonDao.java

package com.llxazy.dao;

import org.springframework.stereotype.Repository;

@Repository("personDao")
@Scope(value="prototype")
public class PersonDao {
}

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

  当定义好基础扫描的包之后,可以排除包中的某些类,使用如下的方式:
    type: 表示指定过滤的规则
    annotation:按照注解进行排除,标注了指定注解的组件不要,expression表示要过滤的注解
    assignable:指定排除某个具体的类,按照类排除,expression表示不注册的具体类名
    aspectj:后面讲aop的时候说明要使用的aspectj表达式,基本不用
    custom:定义一个typeFilter,自己写代码决定哪些类被过滤掉,基本不用
    regex:使用正则表达式过滤,基本不用

<?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
        http://www.springframework.org/schema/context/spring-context.xsd">
    <context:component-scan base-package="com.lliazy" use-default-filters="false">
    <!--指定不扫描哪些组件-->
     <context:exclude-filter type="annotation" expression="org.springframework.stereotype.Controller"/> 

    <!--指定只扫描哪些组件,默认情况下是全部扫描的,所以此时要配置的话需要在component-scan标签中添加 use-default-filters="false"-->   

    <context:include-filter type="assignable" expression="com.llxazy.service.PersonService"/>
</context:component-scan>

</beans>

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

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

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

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

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

      1、匹配上直接进行装配

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

  

  还可以使用@Qualifier注解来指定id的名称,让spring不要使用变量名,当使用@Qualifier注解的时候也会有两种情况:

    1、找到,则直接装配

    2、找不到,就会报错

package com.llxazy.controller;

import com.llxazy.service.PersonService;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Qualifier;
import org.springframework.stereotype.Controller;

@Controller
public class PersonController {

    @Autowired
    @Qualifier("personService")
    private PersonService personService;

    public PersonController() {
        System.out.println("创建对象");
    }

    public void getPerson(){
        personService.getPerson();
    }
}

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

  当方法上有@AutoWired注解时:
    1、此方法在bean创建的时候会自动调用
    2、这个方法的每一个参数都会自动注入值  

  @Qualifier注解也可以作用在属性上,用来被当作id去匹配容器中的对象,如果没有此注解,那么直接按照类型进行匹配

package com.llxazy.controller;

import com.llxazy.dao.PersonDao;
import com.llxazy.service.PersonService;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Qualifier;
import org.springframework.stereotype.Controller;

@Controller
public class PersonController {

    @Qualifier("personService")
    @Autowired
    private PersonService personService;

    public PersonController() {
        System.out.println("创建对象");
    }

    public void getPerson(){
        System.out.println("personController..."+personService);
    }

    @Autowired
    public void test(PersonDao personDao){
        System.out.println("此方法被调用:"+personDao);
    }
    
    @Autowired
    public void test2(@Qualifier("personServiceExt") PersonService personService){
        System.out.println("此方法被调用:"+personService);
    }
}    

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

  在使用自动装配的时候,出了可以使用@AutoWired注解之外,还可以使用@Resource注解,大家需要知道这两个注解的区别。

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

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

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

package com.llxazy.controller;

import com.llxazy.dao.PersonDao;
import com.llxazy.service.PersonService;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Qualifier;
import org.springframework.stereotype.Controller;

import javax.annotation.Resource;

@Controller
public class PersonController {

    @Qualifier("personService")
    @Resource
    private PersonService personService;

    public PersonController() {
        System.out.println("创建对象");
    }

    public void getPerson(){
        System.out.println("personController..."+personService);
        personService.getPerson();
    }

    @Autowired
    public void test(PersonDao personDao){
        System.out.println("此方法被调用:"+personDao);
    }

    @Autowired
    public void test2(@Qualifier("personServiceExt") PersonService personService){
        System.out.println("此方法被调用:"+personService);
    }
}

 

posted @ 2021-07-06 15:31  禾野牧村  阅读(98)  评论(0)    收藏  举报