1. 程式人生 > >【Spring】Spring高階話題[email protected]***註解的工作原理

【Spring】Spring高階話題[email protected]***註解的工作原理

@EnableAspectJAutoProxy

@EnableAspectJAutoProxy註解 啟用Aspect自動代理

 <aop:aspectj-autoproxy/>

開啟對AspectJ自動代理的支援。

在用到AOP的自動代理的時候用,如果你理解了Java的動態代理,很容易的就會熟悉AOP的自動代理的。

@EnableAsync

@EnableAsync註解開啟非同步方法的支援。
這個相信大家都比較熟悉的。對於非同步應該都理解的。
不太熟悉的,可以看這篇部落格:-有示例
【Spring】Spring高階話題-多執行緒-TaskExecutor

@EnableScheduling

@EnableScheduling註解開啟計劃任務的支援。

也就是字面上的意思,開啟計劃任務的支援!
一般都需要@Scheduled註解的配合。

@EnableWebMVC

@EnableWebMVC註解用來開啟Web MVC的配置支援。

也就是寫Spring MVC時的時候會用到。

@EnableConfigurationProperties

@EnableConfigurationProperties註解是用來開啟對@ConfigurationProperties註解配置Bean的支援。

也就是@EnableConfigurationProperties註解告訴Spring Boot 使能支援@ConfigurationProperties

@EnableJpaRepositories

@EnableJpaRepositories註解開啟對Spring Data JPA Repostory的支援。

Spring Data JPA 框架,主要針對的就是 Spring 唯一沒有簡化到的業務邏輯程式碼,至此,開發者連僅剩的實現持久層業務邏輯的工作都省了,唯一要做的,就只是宣告持久層的介面,其他都交給 Spring Data JPA 來幫你完成!

簡單的說,Spring Data JPA是用來持久化資料的框架。

@EnableTransactionManagement

@EnableTransactionManagement註解開啟註解式事務的支援。

註解@EnableTransactionManagement通知Spring,@Transactional註解的類被事務的切面包圍。這樣@Transactional就可以使用了。

@EnableCaching

@EnableCaching註解開啟註解式的快取支援

通過這些簡單的@Enable*可以開啟一項功能的支援,從而避免自己配置大量的程式碼,很大程度上降低了使用難度。

我們一起來觀察下這些@Enable*註解的原始碼,可以發現所有的註解都有一個@Import註解。

@Import註解是用來匯入配置類的,這也就是說這些自動開啟的實現其實是匯入了一些自動配置的Bean。

這些匯入配置方式主要分為以下三種類型。

@Import註解匯入配置方式的三種類型

第一類:直接匯入配置類

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

package org.springframework.scheduling.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.context.annotation.Import;
import org.springframework.scheduling.annotation.SchedulingConfiguration;

@Target({ElementType.TYPE})
@Retention(RetentionPolicy.RUNTIME)
@Import({SchedulingConfiguration.class})
@Documented
public @interface EnableScheduling {
}

直接匯入配置類SchedulingConfiguration,這個類註解了@Configuration,且註冊了一個scheduledAnnotationProcessor的Bean,原始碼如下:

/*
 * Copyright 2002-2015 the original author or authors.
 *
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 *      http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */

package org.springframework.scheduling.annotation;

import org.springframework.beans.factory.config.BeanDefinition;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.context.annotation.Role;
import org.springframework.scheduling.config.TaskManagementConfigUtils;

/**
 * {@code @Configuration} class that registers a {@link ScheduledAnnotationBeanPostProcessor}
 * bean capable of processing Spring's @{@link Scheduled} annotation.
 *
 * <p>This configuration class is automatically imported when using the
 * @{@link EnableScheduling} annotation. See {@code @EnableScheduling}'s javadoc
 * for complete usage details.
 *
 * @author Chris Beams
 * @since 3.1
 * @see EnableScheduling
 * @see ScheduledAnnotationBeanPostProcessor
 */
@Configuration
@Role(BeanDefinition.ROLE_INFRASTRUCTURE)
public class SchedulingConfiguration {

    @Bean(name = TaskManagementConfigUtils.SCHEDULED_ANNOTATION_PROCESSOR_BEAN_NAME)
    @Role(BeanDefinition.ROLE_INFRASTRUCTURE)
    public ScheduledAnnotationBeanPostProcessor scheduledAnnotationProcessor() {
        return new ScheduledAnnotationBeanPostProcessor();
    }

}

第二類:依據條件選擇配置類

EnableAsync 註解核心程式碼:

@Target(ElementType.TYPE)
@Retention(RetentionPolicy.RUNTIME)
@Documented
@Import(AsyncConfigurationSelector.class)
public @interface EnableAsync {
    Class<? extends Annotation> annotation() default Annotation.class;
    boolean proxyTargetClass() default false;
    AdviceMode mode() default AdviceMode.PROXY;
    int order() default Ordered.LOWEST_PRECEDENCE;

}

AsyncConfigurationSelector通過條件來選擇需要匯入的配置類,
AsyncConfigurationSelector的根介面為ImportSelector,這個介面需要重寫selectImports方法,在此方法內進行事先條件判斷。

在下面的原始碼中,若adviceMode為PORXY,則返回ProxyAsyncConfiguration這個配置類。
若activeMode為ASPECTJ,則返回AspectJAsyncConfiguration配置類。
原始碼如下:

public class AsyncConfigurationSelector extends AdviceModeImportSelector<EnableAsync> {

    private static final String ASYNC_EXECUTION_ASPECT_CONFIGURATION_CLASS_NAME =
            "org.springframework.scheduling.aspectj.AspectJAsyncConfiguration";

    /**
     * {@inheritDoc}
     * @return {@link ProxyAsyncConfiguration} or {@code AspectJAsyncConfiguration} for
     * {@code PROXY} and {@code ASPECTJ} values of {@link EnableAsync#mode()}, respectively
     */
    @Override
    public String[] selectImports(AdviceMode adviceMode) {
        switch (adviceMode) {
            case PROXY:
                return new String[] { ProxyAsyncConfiguration.class.getName() };
            case ASPECTJ:
                return new String[] { ASYNC_EXECUTION_ASPECT_CONFIGURATION_CLASS_NAME };
            default:
                return null;
        }
    }

}

第三類:動態註冊Bean

@Target(ElementType.TYPE)
@Retention(RetentionPolicy.RUNTIME)
@Documented
@Import(AspectJAutoProxyRegistrar.class)
public @interface EnableAspectJAutoProxy {
    boolean proxyTargetClass() default false;
}

AspectJAutoProxyRegistrar 事先了ImportBeanDefinitionRegistrar介面,ImportBeanDefinitionRegistrar的作用是在執行時自動新增Bean到已有的配置類,通過重寫方法:

@Override
    public void registerBeanDefinitions(
            AnnotationMetadata importingClassMetadata, BeanDefinitionRegistry registry)

其中,AnnotationMetadata引數用來獲得當前配置類上的註解;
BeanDefinittionRegistry引數用來註冊Bean。
原始碼如下:

class AspectJAutoProxyRegistrar implements ImportBeanDefinitionRegistrar {

    /**
     * Register, escalate, and configure the AspectJ auto proxy creator based on the value
     * of the @{@link EnableAspectJAutoProxy#proxyTargetClass()} attribute on the importing
     * {@code @Configuration} class.
     */
    @Override
    public void registerBeanDefinitions(
            AnnotationMetadata importingClassMetadata, BeanDefinitionRegistry registry) {

        AopConfigUtils.registerAspectJAnnotationAutoProxyCreatorIfNecessary(registry);

        AnnotationAttributes enableAJAutoProxy =
                AnnotationConfigUtils.attributesFor(importingClassMetadata, EnableAspectJAutoProxy.class);
        if (enableAJAutoProxy.getBoolean("proxyTargetClass")) {
            AopConfigUtils.forceAutoProxyCreatorToUseClassProxying(registry);
        }
    }

}

本文章由[諳憶]編寫, 所有權利保留。

相關推薦

SpringSpring高階話題<a href="/cdn-cgi/l/email-protection" class="__cf_email__" data-cfemail="012c41446f60636d64">[email&#160;protected]a>***註解工作原理

@EnableAspectJAutoProxy @EnableAspectJAutoProxy註解 啟用Aspect自動代理 <aop:aspectj-autoproxy/> 開啟對AspectJ自動代理的支援。 在用到AOP的

SpringSpring高階話題-計劃任務<a href="/cdn-cgi/l/email-protection" class="__cf_email__" data-cfemail="a68be6e3c8c7c4cac3f5c5cec3c2d3cacfc8c1">[email&#160;pr

進行本示例的演示,需要先配置好Maven和spring哦、 見:  http://blog.csdn.net/qq_26525215/article/details/53010442 分析 要實現計劃任務,首先通過在配置類註解@EnableScheduling來開

Spring@<a href="/cdn-cgi/l/email-protection" class="__cf_email__" data-cfemail="4b0824253f392427272e390b192e3a3e2e383f062a3b3b22252c">[email&#160;pr

一 淺顯的感性理解 向瀏覽器宣告 @Controller 其作用簡單來說就是對瀏覽器宣告,此類為控制器類 @ResponseBody 作用在方法上,表明此函式返回的內容直接寫入HTTP Response物件 @RestController 是@ResponseBo

Spring定時任務詳解例項<a href="/cdn-cgi/l/email-protection" class="__cf_email__" data-cfemail="92bfd2c1f1faf7f6e7fef7f6">[email&#160;protected]a>

最近在做專案,時間比較緊張,也有比較久沒寫部落格了。 現在專案的Redis快取需要用到定時任務,就學習了一下Spring 的@Scheduled註解。使用起來很簡單。 這個例子是建立在之前我的一篇部落格的例項上面的。 也就是架好了SSM框架。 SSM

Spring註解四、自動裝配@<a href="/cdn-cgi/l/email-protection" class="__cf_email__" data-cfemail="723307061d051b00171654322017011d07001117">[email&#160;protec

四、自動裝配 [email protected]&@Qualifier和@Primary @Autowried是Spring2.5定義的自動裝配的註解,它可以對類成員變數、方法及建構函式進行標註,完成自動裝配的工作。 使用 @Au

Spring高級話題<a href="/cdn-cgi/l/email-protection" class="__cf_email__" data-cfemail="b29ff2f7dcd3d0ded7">[email&#160;protected]a>***註解工作原理

sso metadata bool logs tcl task ota -c ann 出自:http://blog.csdn.net/qq_26525215 @EnableAspectJAutoProxy @EnableAspectJAutoProxy註解 激活Aspe

spring <a href="/cdn-cgi/l/email-protection" class="__cf_email__" data-cfemail="62000d0d16222103010a0703000e07">[email&#160;protected]a>中value的理解

先看原始碼 /** * Names of the caches in which method invocation results are stored. * <p>Names may be used to determine the target cache (or cac

Spring Boot入門篇<a href="/cdn-cgi/l/email-protection" class="__cf_email__" data-cfemail="cde08d9fa8bcb8a8beb99dacbfaca0">[email&#160;protected]a>/@Req

請求引數註解問題 當前臺介面使用GET或POST方式提交資料時,資料編碼格式由請求頭的ContentType指定。 分為以下幾種情況: application/x-www-form-urlencoded 這種情況的資料@RequestParam、@Mode

spring宣告式事務管理方式( 基於tx和aop名字空間的xml配置<a href="/cdn-cgi/l/email-protection" class="__cf_email__" data-cfemail="0922495d7b68677a686a7d6066676865">[email&#

轉自:https://www.cnblogs.com/niceyoo/p/8732891.html 1. 宣告式事務管理分類 宣告式事務管理也有兩種常用的方式, 一種是基於tx和aop名字空間的xml配置檔案,另一種就是基於@Transactional註解。 顯然基於註解的方式更簡單

spring事務(4)-----複習<a href="/cdn-cgi/l/email-protection" class="__cf_email__" data-cfemail="3a494a4853545d7a7b4f4e554d53485f5e">[email&#160;protected]<

什麼是註解 傳統的Spring做法是使用.xml檔案來對bean進行注入或者是配置aop、事物,這麼做有兩個缺點: 1、如果所有的內容都配置在.xml檔案中,那麼.xml檔案將會十分龐大;如果按需求分開.xml檔案,那麼.xml檔案又會非常多。總之這將導致配置檔案的可讀性與可維護性變得很低 2、在開發中

Spring中@<a href="/cdn-cgi/l/email-protection" class="__cf_email__" data-cfemail="c1a2aeafb5b3aeadada481b2a4b3b7a8a2a4">[email&#160;protected]a>@<a h

我是一名Spring 小白 跟單位的小牛牛學習spring框架,總結以下 @controller 控制器(注入服務) 用於標註控制層,相當於struts中的action層 @service 服務(注入dao) 用於標註服務層,主要用來進行業務的邏輯處理 @re

轉載解決方案:<a href="/cdn-cgi/l/email-protection" class="__cf_email__" data-cfemail="2f48465b6f48465b475a4d014c4042">[email&#160;protected]a>出現Permissi

遇到的問題 今天心血來潮,想將intellij上的專案程式碼放到GitHub上管理。 在進行新增遠端庫的時候,出現了:[email protected]出現Permission denied (publickey) 原因是 ./ssh目錄預設在C:\Users\VULCAN\.ssh,而我

spring <a href="/cdn-cgi/l/email-protection" class="__cf_email__" data-cfemail="e5878a8a91a5a08b84878980bdbdbdbd">[email&#160;protected]a>註解程式設計模型分析

@EnableXXXX程式設計模型 在spring boot中,@EnableXXX註解的功能通常是開啟某一種功能。根據某些外部配置自動裝配一些bean,來達到開啟某些功能的目的。光說很抽象,要具體分析。 @Enable模型的實現方式基本有3種。一個基本的@

Spring boot使用總結(三)校驗<a href="/cdn-cgi/l/email-protection" class="__cf_email__" data-cfemail="311c1c717f5e45735d505f5a">[email&#160;protected]a> 使用

spring boot 1.4預設使用 hibernate validator 5.2.4 Final實現校驗功能。hibernate validator 5.2.4 Final是JSR 349 Bean Validation 1.1的具體實現。 一 初步使用

Spring註解<a href="/cdn-cgi/l/email-protection" class="__cf_email__" data-cfemail="7e53533e2e0c111817121b">[email&#160;protected]a>的使用

@Profile的作用:當容器根據標識啟用對應的@Profile註解時,其所關聯的bean類才會註冊到容器。但容器不能或找不到對應的@Profile,就不生成bean例項。 建立配置類MainConf

Spring註解開發<a href="/cdn-cgi/l/email-protection" class="__cf_email__" data-cfemail="96a5bbbbd6dffbe6f9e4e2">[email&#160;protected]a> , FacotryBean 註冊

目錄 @ComponentScan註解用於掃描自己寫的類(@Controller,@Service,@Component,@Repository),用於加入IOC容器中 @Bean 可以把其他包或者自己寫的類加到IOC容器中 @Import 也可以辦

C++error LNK2019: 無法解析的外部符號 <a href="/cdn-cgi/l/email-protection" class="__cf_email__" data-cfemail="a6f9f1cfc8ebc7cfc8e69790">[email&#160;protected

原因:c語言執行時找不到適當的程式入口函式 解決:對於控制檯應用程式 1.選單中選擇 Project->Properties, 彈出Property Pages視窗 2.在左邊欄中依次選擇:Configuration Properties->C/C++->

Shelllinux bash Shell特殊變數:Shell $0, $#, $*, <a href="/cdn-cgi/l/email-protection" class="__cf_email__" data-cfemail="4f6b0f">[email&#160;protected]<

在linux下配置shell引數說明 前面已經講到,變數名只能包含數字、字母和下劃線,因為某些包含其他字元的變數有特殊含義,這樣的變數被稱為特殊變數。  例如,$ 表示當前Shell程序的ID,即pid,看下面的程式碼: $echo $$ 執行結果 29949

Spring 註解中 @<a href="/cdn-cgi/l/email-protection" class="__cf_email__" data-cfemail="622c0d162c170e0e222c0d16270f12161b">[email&#160;protected]a>,@N

首先要清楚的是下邊1,2,3; 且空格是有長度的: 1  @NotNull:不能為null,但可以為empty,沒有Size的約束 2  @NotEmpty :不能為null,且Size>0 3  @NotBlank:只用於String,不能為null且trim()之

Spring中Bean的生命週期之<a href="/cdn-cgi/l/email-protection" class="__cf_email__" data-cfemail="476a6a6a6a6a0705222629">[email&#160;protected]a>方法進行物件的初始化

方法:通過@Bean指定init-method和destroy-method; 注:單例項和原型模式物件的建立時間和初始化銷燬的時間順序不同。 一、單例項模式 1、建立Car例項物件,並建立初始化和銷燬方法 package com.atguigu.bean; imp