1. 程式人生 > >Spring註解版--spring給容器註冊元件的四種方法

Spring註解版--spring給容器註冊元件的四種方法

Spring註解版–spring給容器註冊元件的四種方法:

這是我看網上視訊教程之後,自己整理的,加強記憶。

文章目錄

一. @Configuration&@Bean-自動掃描元件、掃描規則元件

1、建立一個webquick專案,內部新增pom依賴

<dependency>
      <groupId>org.springframework</groupId>
      <artifactId>spring-context</artifactId>
      <version>5.1.2.RELEASE</version>
    </dependency>

給maven工程新增spring-context的依賴。

2、比較xml註冊bean與註解註冊bean

(1)xml配置註冊bean

1544768247996

IOC在專案中新增一個resources資料夾,內部存放所有的配置檔案以及資源。現在我們在內部建立一個bean.xml這個IOC容器的xml配置檔案。

bean.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"
       xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans.xsd">

    <!--<bean></bean>-->
    <bean id="user" class="com.xiaojian.bean.User">
        <property name="username" value="xiaojian"></property>
        <property name="userage" value="11"></property>
    </bean>
</beans>

如圖,我們給容器添加了一個bean,指向我們的一個User的實體類。此處的User的實體類,我們存放在java目錄下的bean資料夾中。
User實體類如下:

package com.xiaojian.bean;

public class User {

    private String username;

    private Integer userage;

    public String getUsername() {
        return username;
    }

    public void setUsername(String username) {
        this.username = username;
    }

    public Integer getUserage() {
        return userage;
    }

    public void setUserage(Integer userage) {
        this.userage = userage;
    }

    @Override
    public String toString() {
        return "User{" +
                "username='" + username + '\'' +
                ", userage='" + userage + '\'' +
                '}';
    }

    public User(String username, Integer userage) {
        this.username = username;
        this.userage = userage;
    }

    public User() {
    }
}

我們在test目錄下面建立MainTest01測試類,測試獲取IOC容器中的bean。

測試類MainTest01:

package com.xiaojian.test;

import com.xiaojian.bean.User;
import org.springframework.context.ApplicationContext;
import org.springframework.context.support.ClassPathXmlApplicationContext;

public class MainTest01 {

    public static void main(String[] args) {
        ApplicationContext ApplicationContext = new ClassPathXmlApplicationContext("bean.xml");
        User user = (User) ApplicationContext.getBean("user");
        System.out.println(user);
        }
}

測試結果:

1544768940929

(2)註解註冊bean

在config目錄下建立MainConfig類,此類為建立bean的配置類。

package com.xiaojian.config;

import com.xiaojian.bean.User;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;

//配置類==配置檔案
@Configuration  //告訴spring這是一個配置類
public class MainConfig {

    //給容器註冊一個bean;型別為返回值的型別;id預設是用方法名作為id(不過我們也可以自己指定id,就是value值)
    @Bean(value = "user01")
    public User user01(){
        return new User("小賤",13);
    }
}

此class類檔案中,@Configuration註解告訴spring這是一個配置類,配置類的作用就是xml配置檔案的作用。

@Bean 註解是給容器註冊一個bean,型別為返回值的型別,id預設是用方法名作為id,不過我們可以自己定義id,也就是@Bean註解下value屬性值。

@Bean註解介面(系統內部的註解,我們直接使用):

//
// Source code recreated from a .class file by IntelliJ IDEA
// (powered by Fernflower decompiler)
//

package org.springframework.context.annotation;

import java.lang.annotation.Documented;
import java.lang.annotation.ElementType;
import java.lang.annotation.Retention;
import java.lang.annotation.RetentionPolicy;
import java.lang.annotation.Target;
import org.springframework.beans.factory.annotation.Autowire;
import org.springframework.core.annotation.AliasFor;

@Target({ElementType.METHOD, ElementType.ANNOTATION_TYPE})
@Retention(RetentionPolicy.RUNTIME)
@Documented
public @interface Bean {
    @AliasFor("name")
    String[] value() default {};

    @AliasFor("value")
    String[] name() default {};

    /** @deprecated */
    @Deprecated
    Autowire autowire() default Autowire.NO;

    boolean autowireCandidate() default true;

    String initMethod() default "";

    String destroyMethod() default "(inferred)";
}

此註解介面中定義了value這個屬性,就是bean的id。當使用value這個屬性的時候,所有通過id想要獲取此bean,必須通過value定義的id,而不是方法名。

我們在test目錄下再定義一個MainTest02這個類檔案,測試註解方式註冊bean。

測試類MainTest02:

package com.xiaojian.test;

import com.xiaojian.bean.User;
import com.xiaojian.config.MainConfig;
import org.springframework.context.ApplicationContext;
import org.springframework.context.annotation.AnnotationConfigApplicationContext;

public class MainTest02 {

    public static void main(String[] args) {

        ApplicationContext applicationContext = new AnnotationConfigApplicationContext(MainConfig.class);
        User user = (User) applicationContext.getBean("user01");
        System.out.println(user);

        //此處的方法是通過型別來獲取所有的bean的集合。
        Map<String, User> beansOfType = applicationContext.getBeansOfType(User.class);
        System.out.println(beansOfType);
        
        
        //此處的方法是通過型別來獲取Bean的名稱,此處是通過User這個類,來獲取Bean的名稱。
        String[] beanNamesForType = applicationContext.getBeanNamesForType(User.class);
        for (String name : beanNamesForType) {
            System.out.println(name);
        }
        
        
        //applicationContext下面還有好多的方法,可以有時間可以自己看看。
        
    }
}

執行結果:

1544770122075

[email protected]ComponentScan包掃描

(1)建立相關的類

首先在xiaojian這個資料夾下面分別建立controller、service、dao這三個資料夾,裡面在分別建立對應的BookController、BookService、BookDao這三個類檔案,同時新增對應的註解。

BookController:

package com.xiaojian.controller;

import org.springframework.stereotype.Controller;

@Controller   //此註解說明這是一個控制器
public class BookController {
}

BookService:

package com.xiaojian.service;

import org.springframework.stereotype.Service;

@Service   //此註解作用是給容器掃描到,說明此類事服務層
public class BookService {
}

BookDao:

package com.xiaojian.dao;

import org.springframework.stereotype.Repository;

@Repository   //此註解是為了給容器掃描到,說明此類是dao層。
public class BookDao {
}

(2)xml配置中的包掃描方式

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">

    <!--  包掃描,只要標註了@Controller、@Service、@Repository、@Component中的任何一個,都會被掃描-->
    <context:component-scan base-package="com.xiaojian"></context:component-scan>
    <!--<bean></bean>-->
    <bean id="user" class="com.xiaojian.bean.User">
        <property name="username" value="xiaojian"></property>
        <property name="userage" value="11"></property>
    </bean>
</beans>

xml檔案中通過<context:component-scan base-package="" />來掃描配置的bean。

(3)註解實現包掃描方式

我們只需要在@Configuration主配置類中新增@ComponentScan( value="com.xiaojian")就可以自動掃描xiaojian這個包下面的所有的添加了@Controller@Service、@Repository@Component

MainConfig主配置類:

package com.xiaojian.config;

import com.xiaojian.bean.User;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.ComponentScan;
import org.springframework.context.annotation.Configuration;

//配置類==配置檔案
@Configuration  //告訴spring這是一個配置類
@ComponentScan(value = "com.xiaojian")
//包掃描路徑,與在xml檔案中配置 <context:component-scan base-package="com.xiaojian"></context:component-scan>  作用一樣。
public class MainConfig {

    //給容器註冊一個bean;型別為返回值的型別;id預設是用方法名作為id(不過我們也可以自己指定id,就是value值)
    @Bean(value = "user01")
    public User user01(){
        return new User("小賤",13);
    }
}

小的測試

在test目錄下新增一個測試類——MainTest03。

MainTest03:

package com.xiaojian.test;

import com.xiaojian.config.MainConfig;
import org.springframework.context.ApplicationContext;
import org.springframework.context.annotation.AnnotationConfigApplicationContext;

public class MainTest03 {

    public static void main(String[] args) {

        ApplicationContext applicationContext = new AnnotationConfigApplicationContext(MainConfig.class);

        //此方法可以獲取所有的bean定義的名字
        String[] beanDefinitionNames = applicationContext.getBeanDefinitionNames();
        for (String name:beanDefinitionNames){
            System.out.println(name);
        }

    }
}

測試結果:

1544772149159

(4)@ComponentScan屬性值

  1. value值:

    value值是說明此掃描的掃描路徑,系統只會掃描路徑下的所有的添加了@Controller@Service、@Repository@Component註解的類。

  2. excludeFilters屬性:

    產生過濾規則,此指定掃描的時候按照什麼規則排除哪些元件。此寫法是一個Filter陣列。

    MainConfig:

    package com.xiaojian.config;
    
    import com.xiaojian.bean.User;
    import org.springframework.context.annotation.Bean;
    import org.springframework.context.annotation.ComponentScan;
    import org.springframework.context.annotation.Configuration;
    import org.springframework.context.annotation.FilterType;
    import org.springframework.stereotype.Controller;
    import org.springframework.stereotype.Service;
    
    //配置類==配置檔案
    @Configuration  //告訴spring這是一個配置類
    @ComponentScan(value = "com.xiaojian",excludeFilters = {
            @ComponentScan.Filter(type = FilterType.ANNOTATION,classes = {Controller.class, Service.class})
    })
    //此處的type中的 FilterType.ANNOTATION表明排除註解方式的配置bean,classes表明排除的配置bean新增的註解的型別(此處主要排除@Controller、@Service兩個註解的配置類)
    //包掃描路徑,與在xml檔案中配置 <context:component-scan base-package="com.xiaojian"></context:component-scan>  作用一樣。
    public class MainConfig {
    
        //給容器註冊一個bean;型別為返回值的型別;id預設是用方法名作為id(不過我們也可以自己指定id,就是value值)
        @Bean(value = "user01")
        public User user01(){
            return new User("小賤",13);
        }
    }
    
    

    執行MainTest03測試類,測試結果:

    1544773543923

    系統的列印日誌中少了BookController、BookService這兩個。

  3. includeFilters屬性:

    產生過濾規則,此指定掃描的時候按照什麼規則只掃描哪些元件。此寫法是一個Filter陣列。

    (與上面相反)

    不過此處需要注意,因為在@ComponentScan中有個屬性useDefaultFilters,預設為true,而我們使用includeFilters屬性的時候,需要將useDefaultFilters設定為false。

    MainConfig:

    package com.xiaojian.config;
    
    import com.xiaojian.bean.User;
    import org.springframework.context.annotation.Bean;
    import org.springframework.context.annotation.ComponentScan;
    import org.springframework.context.annotation.Configuration;
    import org.springframework.context.annotation.FilterType;
    import org.springframework.stereotype.Controller;
    import org.springframework.stereotype.Service;
    
    //配置類==配置檔案
    @Configuration  //告訴spring這是一個配置類
    @ComponentScan(value = "com.xiaojian",includeFilters = {
            @ComponentScan.Filter(type = FilterType.ANNOTATION,classes = {Controller.class})
    },useDefaultFilters = false)  //必須把useDefaultFilters設定為false才能使用includeFilters
    //包掃描路徑,與在xml檔案中配置 <context:component-scan base-package="com.xiaojian"></context:component-scan>  作用一樣。
    public class MainConfig {
    
        //給容器註冊一個bean;型別為返回值的型別;id預設是用方法名作為id(不過我們也可以自己指定id,就是value值)
        @Bean(value = "user01")
        public User user01(){
            return new User("小賤",13);
        }
    }
    
    

    執行MainTest03測試類,測試結果:

    在這裡插入圖片描述

    此處只有一個bookController,因為includeFilters中只有一個Controller通行。

    @ComponentScan是一個可重複寫的註解,我們可以在一個類上多次新增此註解。

    或者我們可以使用@ComponentScans註解,內部新增多個@ComponentScan

(5)@Filter註解type屬性指定掃描規則

  • FilterType.ANNOTATION:按照註解的方式(最常用)
  • FilterType.ASPECTJ:使用ASPECTJ表示式(幾乎不常用)
  • FilterType.REGEX:使用正則表示式
  • FilterType.ASSIGNABLE_TYPE:按照給定的型別
@ComponentScan(value = "com.xiaojian",includeFilters = {
        @ComponentScan.Filter(type = FilterType.ANNOTATION,classes = {Controller.class}),
        @ComponentScan.Filter(type = FilterType.ASSIGNABLE_TYPE,classes = {BookService.class})
},useDefaultFilters = false)

在MainConfig類檔案的@ComponentScanincludeFilters屬性中新增一個FilterType.ASSIGNABLE_TYPE的Filter,此Filter通過BookService這個指定的類檔案。

執行MainTest03測試類,測試結果:

1544775256737

  • FilterType.CUSTOM:使用自定義規則

使用自定義規則的時候,這個值必須是一個TypeFilter規則的實現類。

首先我們在xiaojian這個資料夾下建立一個impls資料夾,在此資料夾下建立一個MyTypeFilter類去實現TypeFilter這個介面,介面中有一個返回boolean型別值的方法。

package com.xiaojian.impls;

import org.springframework.core.io.Resource;
import org.springframework.core.type.AnnotationMetadata;
import org.springframework.core.type.ClassMetadata;
import org.springframework.core.type.classreading.MetadataReader;
import org
            
           

相關推薦

Spring註解--spring容器註冊元件方法

Spring註解版–spring給容器註冊元件的四種方法: 這是我看網上視訊教程之後,自己整理的,加強記憶。 文章目錄 Spring註解版--spring給容器註冊元件的四種方法: 一. `@Configuration`&`@Bean`-

spring註解 使用FactoryBean(工廠Bean)註冊元件

一般在容器中註冊元件都使用@Bean或者之前講的@Import,當然還有包掃描+元件標註註解的方法。今天學了一個工廠Bean的方式註冊元件,正好也在學設計模式,研究研究 玩FactoryBean需要搞一個類去實現它,老規矩,類名MyFactoryBean import o

SpringBoot容器註冊元件方法(簡易

本文介紹的方法比較簡潔,需要有Spring基礎 方法一:包掃描+註解 1.配置類,標明註解掃描的範圍 //告訴Spring這是一個配置類 @Configuration //註解所掃描的範圍,類似於spring配置檔案的 context:component-scan

######Spring第5天ssh整合(註解)難理解知識點:【自定義 方法註解的方式】dao注入sessionFactory屬性+【搞清@Autowared和@Resource含義】

===【方法加註解的方式】給dao注入sessionFactory屬性(繼承父類的屬性),第一次見!===具體怎麼用的,看原始碼。(後面有寫) 以前都是屬性+註解注入屬性。 [email protected]和@Resource到底是幹嘛的? 剛學IOC時可能能

Spring註解驅動開發(1):容器

核心容器: Demo: pom.xml <project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:s

Spring Web MVC 核心元件第二方法(用註解方法

Spring Web MVC 核心元件 Spring Web MVC提供了M、V和C相關的主要實現元件,具體如下: DispatcherServlet(控制器,請求入口) HandlerMapping(控制器,請求派發) Controller(控制器,請求處理流程) ModelA

spring註解 TypeFilter自定義掃描bean規則

最近決定從學一下spring,以前學的時候很多東西就不怎麼理解,這裡開始好好學學。 今天看了自定義TypeFilter,在掃描包的時候可能會用到吧。 @ComponentScan(value = "top.blogs", includeFilters = {@Filter

Spring註解--Bean的生命週期

Spring註解--Bean的宣告週期 @[TOC](Spring註解--Bean的宣告週期) Bean的生命週期 1.Bean的生命週期: 2.Spring容器來管理Bean的生命週期:

從零寫Spring註解框架系列 IoC篇 (2)實現 @Component、@Autowired、@Qualifier註解

本文承接了上一篇文章的思路進行程式碼實現,並搭建起一個基本可用的基於@Component、@Autowired、@Qualifier 註解的 IoC 框架。 專案 Github 地址為:https://github.com/linshenkx/winter-core 相關文章地址:從

從零寫Spring註解框架系列 IoC篇 (1) 框架設計

本文的註解版IoC框架跟其他手寫IoC框架的不同之處在與:在實現了 @Component 和 @Autowired 的同時還實現了@Qualifier,並解決單例模式下迴圈依賴的問題,以上3個註解的使用效果參照 Spring 。 專案 Github 地址為:https://githu

Spring 註解簡單例項之強大的@Component(二)

1 接上一篇文章<Spring 註解版簡單例項(一)>,此處為 @Component與@Resource相結合   在applicationContext.xml 檔案中使用<context:component-scan>的效果,大大的減少了配置檔案

Spring(五)核心容器 - 註冊 Bean、BeanDefinitionRegistry 簡介

目錄 前言 正文 1、BeanDefinitionRegistry 簡介 2、registerBeanDefinition 方法註冊 Bean 最後

Spring(六)核心容器 - 註冊單例 Bean 例項、SingletonBeanRegistry 簡介

前言 上篇文章我們對註冊 Bean 的核心類 BeanDefinitionRegistry 進行了討論,這裡的註冊 Bean 是指儲存 Bean 的相關資訊,也就是將 Bean 定義成 BeanDefinition,然後放入容器中。除此之外,Spring 還提供一個統一操作單例 Bean 例項的類 Singl

Spring容器托管兩方法

class new 編程 異常 common dao層 容器 業務層 spring容器 Spring最核心的就是IOC(控制反轉)和AOP(面向切面編程)。 IOC可以理解為把Spring當做一個容器,用來管理各種service、dao等。不用再去手動new。 將servi

Spring Web MVC 核心元件第一方法

Spring Web MVC 核心元件 Spring Web MVC提供了M、V和C相關的主要實現元件,具體如下: DispatcherServlet(控制器,請求入口) HandlerMapping(控制器,請求派發) Controller(控制器,請求處理流程) ModelA

Spring+MyBatis整合、介面實現元件方法、整合流程

Spring+Mybatis mybatis-spring.jar整合包 MapperFactoryBean元件,封裝了根據Mapper對映器介面生成實現元件的功能 結合 先把包都引入 ioc aop dao dbcp 當然在之前的Mybatis下增

Spring之面向切面程式設計(AOP)通知

面向切面程式設計(AOP)面向切面的程式設計:指很多功能都有重複的程式碼,把這些重複的程式碼獨立出來實現,再在執行的時候動態加入“切面類程式碼”。AOP是一種設計思想,和具體的程式碼實現無關。優點:      A、把共性功能和核心業務功能解耦。      B、共性程式碼的複用

spring mvc 防止重複提交表單的兩方法,推薦第二

第一種方法:判斷session中儲存的token 比較麻煩,每次在提交表單時都必須傳入上次的token。而且當一個頁面使用ajax時,多個表單提交就會有問題。 註解Token程式碼: package com.thinkgem.jeesite.common.re

如何取得Spring管理的bean (請用第3方法

  如何取得Spring管理的bean  (請用第3種方法): 1、servlet方式載入時, 【web.xml】 Xml程式碼 <servlet>  <servlet-name>springMVC</servlet-name> 

spring中通過constructor來注入引數的方式

spring中可以通過constructor來注入所需要的引數。一共有四種的方法。 1.通過建構函式注入 (原始方式) 2.根據構造器引數的型別 3.根據索引index注入 4.根據引數名稱注入 詳細