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的效果。

  • 相关阅读:
    Vasya and Endless Credits CodeForces
    Dreamoon and Strings CodeForces
    Online Meeting CodeForces
    数塔取数 基础dp
    1001 数组中和等于K的数对 1090 3个数和为0
    1091 线段的重叠
    51nod 最小周长
    走格子 51nod
    1289 大鱼吃小鱼
    POJ 1979 Red and Black
  • 原文地址:https://www.cnblogs.com/yy3b2007com/p/11862742.html
Copyright © 2011-2022 走看看