zoukankan      html  css  js  c++  java
  • Spring(二十三):Spring自动注入的实现方式

    注解注入顾名思义就是通过注解来实现注入,Spring和注入相关的常见注解包含:Autowrired/Resource/Qualifier/Service/Controller/Repository/Component。

    1. Autowired:自动注入,自动从spring的上下文找到合适的bean来注入;
    2. Resource:用来指定bean名称注入;
    3. Qualifier和Autowired配合使用:指定bean的名称来注入;
    4. Service、Contoller、Repository分别标记类:Service层类、Contoller层类、数据层存储层的类,Spring扫描注解配置时,会标记这些类要生成bean;
    5. Component是一种泛指:标记类是组件,Spring扫描注解配置时,会标记这些类要生成bean。

    它们之间的区别:

    • Autowired、Resource用来修饰字段、构造函数、或者设置方法实现注入的;
    • Service、Controller、Repository、Component是修饰类,标记这些类要生成bean。

    接下来我们新建一个maven项目来看看spring注解自动注入的使用:

    使用AnnotationConfigApplicationContext(basePackages)初始化ApplicationContext方式

    1)新家maven项目(Learn-Spring-01)
    在Pom.xml引入spring依赖:

        <properties>
            <project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
            <maven.compiler.source>1.8</maven.compiler.source>
            <maven.compiler.target>1.8</maven.compiler.target>
            <!--Spring版本号 -->
            <org.springframework.version>5.2.0.RELEASE</org.springframework.version>
        </properties>
    
        <dependencies>
            <dependency>
                <groupId>org.springframework</groupId>
                <artifactId>spring-webmvc</artifactId>
                <version>${org.springframework.version}</version>
            </dependency>
            。。。
        </dependencies>

    2)新建Article和ArticleDao类,并给ArticleDao类上加上 @Repository 注解
    Article实体类:

    package com.dx.test.model;
    
    public class Article {
        private Long id;
        private String title;
        private String author;
        private String content;
    
        。。。。
    
        @Override
        public String toString() {
            return "Article [id=" + id + ", title=" + title + ", author=" + author + ", content=" + content + "]";
        }
    }

    ArticleDao类(数据操作类):

    package com.dx.test.dao;
    
    import org.springframework.stereotype.Repository;
    
    import com.dx.test.model.Article;
    
    @Repository
    public class ArticleDao {
        /**
         * 根据文章id,查询文章详情实体
         * 
         * @param id 文章id
         * @return 返回查找到的文章详情
         */
        public Article getById(Long id) {
            Article article = new Article();
            article.setId(1L);
            article.setTitle("Test Article");
            article.setAuthor("Admin");
            article.setContent("The Article's Content");
    
            return article;
        }
    }

    3)新建Service类ArticleService,并在ArticleService类上加上 @Service 注解,在这个类中定义 ArtileDao的字段,并通过 @Autowired 来修饰该字段,这样上面定义的 ArticleDao 类的实例就会自动被注入到 ArticleService 的实例中:

    package com.dx.test.service;
    
    import org.springframework.beans.factory.annotation.Autowired;
    import org.springframework.stereotype.Service;
    
    import com.dx.test.dao.ArticleDao;
    import com.dx.test.model.Article;
    
    @Service
    public class ArticleService {
        @Autowired
        private ArticleDao articleDao;
    
        /**
         * 根据文章id,查询文章实体详情
         * 
         * @param id 文章id
         * @return 返回查找文章详情
         */
        public Article getById(Long id) {
            return articleDao.getById(id);
        }
    }

    注意:@Autowired 注解有一个可以为空的required属性,可以用来指定字段是否是必须的,如果必须的,则在找不到合适的实例时会抛出异常。
    4)在com.dx.test.App的main方法中使用Spring代码方式自动注入ArticleDao、ArticleService。

    package com.dx.test;
    
    import org.springframework.context.ApplicationContext;
    import org.springframework.context.annotation.AnnotationConfigApplicationContext;
    
    import com.dx.test.model.Article;
    import com.dx.test.service.ArticleService;
    
    /**
     * Hello SpringFramework!
     */
    public class App {
        public static void main(String[] args) {
            ApplicationContext applicationContext = new AnnotationConfigApplicationContext("com.dx.test.dao",
                    "com.dx.test.service");
            ArticleService articleService = applicationContext.getBean(ArticleService.class);
            Article article = articleService.getById(1L);
            System.out.println(article);
        }
    }

    上面的main方法中首先我们初始化了applicationContext实例,它是AnnonationConfigApplicationContext,它的构造函数接受 basePackages 的名称,来限定扫描的package范围。然后就可以通过applicationContext#getBean()方法获得 ArticleService 的实例。

    此时运行控制打印信息如下:

    Article [id=1, title=Test Article, author=Admin, content=The Article's Content]

    使用代码注入+spring xml配置文件方式

    实际上在SSM(Spring+SpringMVC+Mybatis)项目中,更多的习惯于使用注解+spring xml配置方式,实现自动注入。

    在maven测试工程中的src/main/resources下,新建applicationContext.xml的spring配置文件,其内容如下:

    实际上在SSM(Spring+SpringMVC+Mybatis)项目中,更多的习惯于使用注解+spring xml配置方式,实现自动注入。
    在maven测试工程中的src/main/resources下,新建applicationContext.xml的spring配置文件,其内容如下:
    <?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-4.0.xsd
     http://www.springframework.org/schema/context
     http://www.springframework.org/schema/context/spring-context-4.0.xsd ">
    
        <!-- bean annotation driven -->
        <context:annotation-config />
        <context:component-scan base-package="com.dx.test.dao,com.dx.test.service" >
        </context:component-scan>
    
        <bean id="testArticleDao" class="com.dx.test.dao.ArticleDao" />
        
     </beans>

    在上面配置中,我们通过 <context:annotation-config /> 和 <context:component-scan ... /> 两个配置节点,来指定要扫描注解注入,然后又定义了一个 id 为 testArticleDao 的bean。
    因为这里我们使用注解+spring xml配置的方式实现自动注入,那么在初始化ApplicationContext类的方式就需要修改下,加载配置文件方式在Spring中包含两个接口:ClassPathXmlApplicationContext 或 FileSystemXmlApplicationContext,这里我们采用 ClassPathXmlApplicationContext 方式来实现初始化ApplicationContext。实现代码如下:

    package com.dx.test;
    
    import org.springframework.context.ApplicationContext;
    import org.springframework.context.support.ClassPathXmlApplicationContext;
    
    import com.dx.test.model.Article;
    import com.dx.test.service.ArticleService;
    
    /**
     * Hello SpringFramework!
     */
    public class App {
        public static void main(String[] args) {
            ApplicationContext applicationContext = new ClassPathXmlApplicationContext("applicationContext.xml");
            ArticleService articleService = applicationContext.getBean(ArticleService.class);
            Article article = articleService.getById(1L);
            System.out.println(article);
        }
    }

    运行程序输出为:

    Article [id=1, title=Test Article, author=Admin, content=The Article's Content]

    上面applicationContext.xml中我们定义了一个id为 testArticleDao 的bean,那么在 ArticleService 中注入 ArticleDao的bean时,我们可以通过@Resource(name="testArticleDao")的方式注入:

    @Resources(name="testArticleDao")
    private ArticleDao articleDao;

    当然我们也可以使用 @Qualifier("testArticleDao")+@Autowired 的方式替代 @Resources(mane="testArticleDao")的方式。

    @Autowired
    @Qualifier("testArticleDao")
    private ArticleDao articleDao;

    注意:

    1)Resource本身不是spring提供的,从它的命名空间可以得知:javax.annotation.Resource;

    2)@Resource注解实现的效果等同于 @Autowired+@Qualifier的效果。

  • 相关阅读:
    调整数组顺序使奇数位于偶数前面
    网站远程附件存储到 OSS
    平滑升级mariadb
    在Apache服务器上安装SSL证书
    复试-英语
    部署博客(docker)
    远程连接Windows
    Ultimate SLAM?利用事件相机解锁高速运动、高动态范围场景
    LRNNet:轻量级FCB& SVN实时语义分割
    3D目标检测深度学习方法中voxel-represetnation内容综述(三)
  • 原文地址:https://www.cnblogs.com/yy3b2007com/p/11862742.html
Copyright © 2011-2022 走看看