欢迎您访问程序员文章站本站旨在为大家提供分享程序员计算机编程知识!
您现在的位置是: 首页  >  IT编程

基于注解的IOC配置

程序员文章站 2022-07-01 14:31:05
基于注解的IOC配置 这种配置,我们需要建立一个容器(我这里创建容器的范围大点)

基于注解的ioc配置

  • 这种配置,我们需要建立一个容器(我这里创建容器的范围大点)

    <?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">
    ​
        <!-- 读取配置文件时,告知spring在创建容器时要扫描的包,配置所需要的标签不是在beans的约束中,而是一个
            名称为context名称空间的约束中
         -->
        <context:component-scan base-package="com.mypro"></context:component-scan>
    </beans>
  • 用于创建bean对象的注解

    • 简述:相当于在xml配置中编写一个bean标签的功能

    • @component

      • 作用:把当前类对象存入spring容器中

      • 属性:value:用于指定bean的id;默认是首写字母小写的类名称

    • @controller: 一般用在表现层

    • @service: 一般用在业务层

    • @repository: 一般用在持久层

    • 以上三种注解和第一种注解的作用和属性是一样的

      package com.mypro.service.impl;
      ​
      import com.mypro.dao.userdao;
      import com.mypro.dao.impl.userdaoimpl;
      import com.mypro.service.userservice;
      import org.springframework.stereotype.service;
      ​
      @service(value = "userservice")
      public class userserviceimpl implements userservice {
      ​
          private userdao userdao = new userdaoimpl();
      ​
          @override
          public void saveuser() {
              userdao.saveuser();
          }
      }
  • 用于注入数据的注解

    • 简述:相当于xml配置文件中bean标签编写一个property标签的功能

    • @autowired

      • 作用:只要容器中有唯一的bean对象类型和要注入的变量类型匹配,就可以自动按照类型注入;如果没有任何的bean的类型和要注入的变量匹配,程序就报错;如果有多个匹配,但是可以根据变量名和注入bean的id匹配,若无匹配则报错

      • 作用域:可以是变量名上,可以是方法名上

      • 细节:不需要setter方法了

        package com.mypro.service.impl;
        ​
        import com.mypro.dao.userdao;
        import com.mypro.service.userservice;
        import org.springframework.stereotype.service;
        ​
        @service(value = "userservice")
        public class userserviceimpl implements userservice {
            @autowired
            private userdao userdao;
        ​
            @override
            public void saveuser() {
                userdao.saveuser();
            }
        }
    • @qualifier

      • 作用:就是解决上述多个匹配结果(原因是至少有两个实现类实现了userdao接口),可以用此注解来指定要注解的类,不能单独使用,需要和@autowired一起使用

      • 属性:value:指定的注入bean的id

      • 假设userdaoimpl2也实现了userdao接口,并且将此类对象存入spring容器中

        package com.mypro.service.impl;
        ​
        import com.mypro.dao.userdao;
        import com.mypro.service.userservice;
        import org.springframework.stereotype.service;
        ​
        @service(value = "userservice")
        public class userserviceimpl implements userservice {
            @autowired
            @qualifier(value="userdaoimpl2")
            private userdao userdao;
        ​
            @override
            public void saveuser() {
                userdao.saveuser();
            }
        }
    • resource

      • 作用:就是简化上述两个注解的使用

      • 属性:name:指定的注入bean的id

    • @value

      • 作用:用于注入基本数据类型和string类型

      • 属性:value:用于指定数据的值,可以使用spring的spel表达式(${})

    • 注意事项:前三种注解只能注解其他bean类型的数据,集合类型的数据注入方式只能通过xml配置文件实现

基于注解完成ioc配置(案例)一定参考上一篇的“基于xml文件的ioc配置”

  • 主配置文件、实体类、测试类、业务层接口、持久层接口这届个文件都可以不用改

  • 事先创建一个大容器(mywordbean.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">
    ​
        <!-- 读取配置文件时,告知spring在创建容器时要扫描的包,配置所需要的标签不是在beans的约束中,而是一个
            名称为context名称空间的约束中
         -->
        <context:component-scan base-package="com.mypro"></context:component-scan>
        <!-- 配置queryrunner对象 -->
        <bean id="runner" class="org.apache.commons.dbutils.queryrunner" scope="prototype">
            <!-- 注入数据源 -->
            <constructor-arg name="ds" ref="datasource"></constructor-arg>
        </bean>
        <!-- 配置数据源 -->
        <bean id="datasource" class="com.mchange.v2.c3p0.combopooleddatasource">
            <!-- 连接数据库 -->
            <property name="driverclass" value="com.mysql.jdbc.driver"></property>
            <property name="jdbcurl" value="jdbc:mysql://localhost:3306/myword"></property>
            <property name="user" value="root"></property>
            <property name="password" value="123456"></property>
        </bean>
    ​
    </beans>

     

  • 业务层实现类

    //1、在业务层实现类名上添加一个容器注解@service(value = "wordsservice")
    //2、在private wordsdao wordsdao上添加一个注入数据的注解@autowired
    //3、该变量的setter方法可有可无
  • 持久层实现类

    //1、在业务层实现类名上添加一个容器注解@repository(value = "wordsdao")
    //2、在private queryrunner runner上添加一个注入数据的注解@autowired
    //3、该变量的setter方法可有可无
  • 这种spring ioc配置并不完全基于注解的方式,以下就需要使用spring的新注解来完全替代xml配置,浏览时建议配置文件和配置类对比浏览

    • 首先我们需要创建一个类,并且指定当前类是配置类。使用@configuration注解指定,如果在读取时的参数已经指定了配置类为参数时,就可以省略不写;扫描的其他包下的配置类或者扫描当前包下的其他配置类都要写注解,否则就不是配置类了

    • 读取配置类时,需要读取我们自己创建的类。使用@componentscan注解指定扫描的包

      • 属性:value和basepackages的作用是一样的,用于指定要扫描的包,使用此注解等就等同上述的<context:component-scan base-package="com.mypro"></context:component-scan>

    • 导入配置类时,可以在@componentscan下添加@import(参数),参数就是配置类的字节码文件(类名.class),导入之后,导入的配置类就可以不写@configuration注解

    • 像数据库这种连接数据信息比较隐秘或者统一管理这种数据,我们通常将连接放置在properties文件中,这样在配置类上使用注解@propertysource("***.properties"),然后就可以在变量使用@value("${变量名}"),变量名就是properties文件里面的变量名

    • @bean用于把当前方法的返回值作为bean对象存入spring的ioc容器中

      • 属性:name用于指定bean的id,默认是当前方法的名称

      • 细节:当我们使用注解配置方法时,如果有参数,spring框架会去容器查找可用的bean对象,查询规则和@autowired一样

      package config;
      ​
      import com.mchange.v2.c3p0.combopooleddatasource;
      import org.apache.commons.dbutils.queryrunner;
      import org.springframework.context.annotation.bean;
      import org.springframework.context.annotation.componentscan;
      import org.springframework.context.annotation.configuration;
      ​
      import javax.sql.datasource;
      ​
      @configuration
      @componentscan(value = "com.mypro")
      @propertysource("jdbcconfig.xml")
      public class springconfiguration {
          @value("${jdbc.driver}")
          private string driver;
          @value("${jdbc.url}")
          private string url;
          @value("${jdbc.username}")
          private string username;
          @value("${jdbc.password}")
          private string password;
      ​
          /**
           * 用于创建一个queryrunner对象
           * @param datasource
           * @return
           */
          @bean(value = "runner")
          @scope("prototype")
          public queryrunner createqueryrunner(datasource datasource){
              return new queryrunner(datasource);
          }
      ​
          /**
           * 配置连接数据库的资源
           * @return
           */
          @bean(value = "datasource")
          public datasource createdatasource(){
              try{
              combopooleddatasource ds = new combopooleddatasource();
                  ds.setdriverclass(driver);
                  ds.setjdbcurl(url);
                  ds.setuser(username);
                  ds.setpassword(password);
                  return ds;
              }catch (exception e){
                  throw new runtimeexception(e);
              }
          }
      }
    • 由于不再是读取xml配置文件,而是读取配置类,读取配置类的类名是annotationconfigapplicationcontext。只需要在测试类中的去去配置文件改掉即可

      applicationcontext ac = new annotationconfigapplicationcontext(springconfiguration.class);