1. 程式人生 > >SpringBoot5-spring高階話題-組合註解與元註解,@Enable*註解的工作原理,測試

SpringBoot5-spring高階話題-組合註解與元註解,@Enable*註解的工作原理,測試

一:組合註解與元註解

      從spring2開始,為了響應JDK1.5推出的註解供暖,spring開始大量加入註解來替代xml配置。spring的註解主要用來配置和注入bean,以及AOP相關的配置(@Transactional)。隨著註解的大量使用,尤其相同的多個註解用到各個類或方法中,會相當繁瑣。這就是所謂的樣板程式碼,是spring設計的原則中要消除的程式碼。

      所謂元註解其實就是可以註解到別的註解上的註解,被註解的註解稱之為組合註解,組合註解具備註解其上的元註解的功能。spring的很多註解都可以作為元註解,而且spring本身已經有很多組合註解,如@Configuration就是一個組合@Component註解,表明這個類其實也是一個Bean。

      前面我們大量使用了@Configuration和@ComponentScan註解到配置類上,下面我們把這兩個註解組成一個組合註解。

     示例:

package jack.ch3.annotation;

import org.springframework.context.annotation.ComponentScan;
import org.springframework.context.annotation.Configuration;

import java.lang.annotation.*;

/**
 * Created by jack on 2017/7/15.
 * 組合註解
 */
@Target(ElementType.TYPE)
@Retention(RetentionPolicy.RUNTIME)
@Documented
@Configuration //組合@Configuration元註解
@ComponentScan //組合@ComponentScan元註解
public @interface WiselyConfiguration {
    //覆蓋value引數
    String [] value() default {};
}


演示服務的Bean:

package jack.ch3.annotation;

import org.springframework.stereotype.Service;

/**
 * Created by jack on 2017/7/15.
 */
@Service
public class DemoService {
    public void outputResult(){
        System.out.println("從組合註解配置照樣獲取的Bean");
    }
}


  配置類:

package jack.ch3.annotation;

/**
 * Created by jack on 2017/7/15.
 */
//使用@WiselyConfiguration組合註解替代@Configuration和@ComponentScan
@WiselyConfiguration("jack.ch3.annotation")
public class DemoConfig {
}


  測試程式碼如下:

package jack.ch3.annotation;

import jack.ch3.conditional.ConditionConfig;
import jack.ch3.conditional.ListServer;
import org.springframework.context.annotation.AnnotationConfigApplicationContext;

/**
 * Created by jack on 2017/7/15.
 */
public class MainTest12 {
    public static void main(String [] args){
        //AnnotationConfigApplicationContext作為spring容器,接受一個配置類作為引數
        AnnotationConfigApplicationContext context = new AnnotationConfigApplicationContext(DemoConfig.class);
        DemoService demoService = context.getBean(DemoService.class);
        demoService.outputResult();
        context.close();
    }
}


   執行程式,輸出如下:

D:\java\jdk1.8.0_111\bin\java -Didea.launcher.port=7535 "-Didea.launcher.bin.path=D:\programmingsoftware\IDEA\JetBrains\IntelliJ IDEA 2016.3.2\bin" -Dfile.encoding=UTF-8 -classpath "D:\java\jdk1.8.0_111\jre\lib\charsets.jar;D:\java\jdk1.8.0_111\jre\lib\deploy.jar;D:\java\jdk1.8.0_111\jre\lib\ext\access-bridge-64.jar;D:\java\jdk1.8.0_111\jre\lib\ext\cldrdata.jar;D:\java\jdk1.8.0_111\jre\lib\ext\dnsns.jar;D:\java\jdk1.8.0_111\jre\lib\ext\jaccess.jar;D:\java\jdk1.8.0_111\jre\lib\ext\jfxrt.jar;D:\java\jdk1.8.0_111\jre\lib\ext\localedata.jar;D:\java\jdk1.8.0_111\jre\lib\ext\nashorn.jar;D:\java\jdk1.8.0_111\jre\lib\ext\sunec.jar;D:\java\jdk1.8.0_111\jre\lib\ext\sunjce_provider.jar;D:\java\jdk1.8.0_111\jre\lib\ext\sunmscapi.jar;D:\java\jdk1.8.0_111\jre\lib\ext\sunpkcs11.jar;D:\java\jdk1.8.0_111\jre\lib\ext\zipfs.jar;D:\java\jdk1.8.0_111\jre\lib\javaws.jar;D:\java\jdk1.8.0_111\jre\lib\jce.jar;D:\java\jdk1.8.0_111\jre\lib\jfr.jar;D:\java\jdk1.8.0_111\jre\lib\jfxswt.jar;D:\java\jdk1.8.0_111\jre\lib\jsse.jar;D:\java\jdk1.8.0_111\jre\lib\management-agent.jar;D:\java\jdk1.8.0_111\jre\lib\plugin.jar;D:\java\jdk1.8.0_111\jre\lib\resources.jar;D:\java\jdk1.8.0_111\jre\lib\rt.jar;E:\webworkspace\IdeaProjects\springstudy1\target\classes;C:\Users\wj\.m2\repository\org\springframework\spring-context\4.1.6.RELEASE\spring-context-4.1.6.RELEASE.jar;C:\Users\wj\.m2\repository\org\springframework\spring-beans\4.1.6.RELEASE\spring-beans-4.1.6.RELEASE.jar;C:\Users\wj\.m2\repository\org\springframework\spring-core\4.1.6.RELEASE\spring-core-4.1.6.RELEASE.jar;C:\Users\wj\.m2\repository\commons-logging\commons-logging\1.2\commons-logging-1.2.jar;C:\Users\wj\.m2\repository\org\springframework\spring-expression\4.1.6.RELEASE\spring-expression-4.1.6.RELEASE.jar;C:\Users\wj\.m2\repository\org\springframework\spring-aop\4.1.6.RELEASE\spring-aop-4.1.6.RELEASE.jar;C:\Users\wj\.m2\repository\aopalliance\aopalliance\1.0\aopalliance-1.0.jar;C:\Users\wj\.m2\repository\org\aspectj\aspectjrt\1.8.5\aspectjrt-1.8.5.jar;C:\Users\wj\.m2\repository\org\aspectj\aspectjweaver\1.8.5\aspectjweaver-1.8.5.jar;C:\Users\wj\.m2\repository\commons-io\commons-io\2.3\commons-io-2.3.jar;C:\Users\wj\.m2\repository\javax\annotation\jsr250-api\1.0\jsr250-api-1.0.jar;D:\programmingsoftware\IDEA\JetBrains\IntelliJ IDEA 2016.3.2\lib\idea_rt.jar" com.intellij.rt.execution.application.AppMain jack.ch3.annotation.MainTest12
七月 15, 2017 3:27:09 下午 org.springframework.context.annotation.AnnotationConfigApplicationContext prepareRefresh
資訊: Refreshing org.spring[email protected]5d099f62: startup date [Sat Jul 15 15:27:09 CST 2017]; root of context hierarchy
從組合註解配置照樣獲取的Bean
七月 15, 2017 3:27:09 下午 org.springframework.context.annotation.AnnotationConfigApplicationContext doClose
資訊: Closing org.spring[email protected]5d099f62: startup date [Sat Jul 15 15:27:09 CST 2017]; root of context hierarchy

Process finished with exit code 0


二:@Enable*註解的工作原理

    在前面我們通過@EnableAspectJAutoProxy開啟對AspectJ自動代理的支援。

    @EnableAsync開啟非同步方法的支援

    @EnableScheduling開啟計劃任務的支援

    @EnableWebMvc開啟Web MVC的配置支援

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

    @EnableJpaRepositor開啟對Spring Data JPA Repository的支援

    @EnableTransactionManagement開啟註解事務的支援

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

        通過簡單的@Enable*來開啟一項功能的支援,從而避免自己配置大量的程式碼,大大降低了使用難度。下面看看實現該功能的原理。

       通過觀察這些@Enable*註解的原始碼,我們發現所有的註解都有一個@Import註解,@Import是用來匯入配置類的,這也意味著這些自動開啟的實現其實是匯入一些自動配置的bean。這些匯入的配置方式主要分為以下三種類型。

     1,第一類:直接匯入配置類

//
// 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,原始碼如下:
//
// Source code recreated from a .class file by IntelliJ IDEA
// (powered by Fernflower decompiler)
//

package org.springframework.scheduling.annotation;

import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.context.annotation.Role;
import org.springframework.scheduling.annotation.ScheduledAnnotationBeanPostProcessor;

@Configuration
public class SchedulingConfiguration {
    public SchedulingConfiguration() {
    }

    @Bean(
        name = {"org.springframework.context.annotation.internalScheduledAnnotationProcessor"}
    )
    @Role(2)
    public ScheduledAnnotationBeanPostProcessor scheduledAnnotationProcessor() {
        return new ScheduledAnnotationBeanPostProcessor();
    }
}


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

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

package org.springframework.scheduling.annotation;

import java.lang.annotation.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.AdviceMode;
import org.springframework.context.annotation.Import;
import org.springframework.scheduling.annotation.AsyncConfigurationSelector;

@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 2147483647;
}

AsyncConfigurationSelector通過條件來選擇需要匯入的配置類,AsyncConfigurationSelector的根介面為ImportSelector,這個介面需重寫selectImports方法,在此方法內進行事先條件判斷。此例中,若adviceMode為PORXY,則返回ProxyAsyncConfiguration這個配置類;若activeMode為ASPECTJ,則返回AspectJAsyncConfiguration配置類,原始碼如下:
//
// Source code recreated from a .class file by IntelliJ IDEA
// (powered by Fernflower decompiler)
//

package org.springframework.scheduling.annotation;

import org.springframework.context.annotation.AdviceMode;
import org.springframework.context.annotation.AdviceModeImportSelector;
import org.springframework.scheduling.annotation.EnableAsync;
import org.springframework.scheduling.annotation.ProxyAsyncConfiguration;

public class AsyncConfigurationSelector extends AdviceModeImportSelector<EnableAsync> {
    private static final String ASYNC_EXECUTION_ASPECT_CONFIGURATION_CLASS_NAME = "org.springframework.scheduling.aspectj.AspectJAsyncConfiguration";

    public AsyncConfigurationSelector() {
    }

    public String[] selectImports(AdviceMode adviceMode) {
        switch(null.$SwitchMap$org$springframework$context$annotation$AdviceMode[adviceMode.ordinal()]) {
        case 1:
            return new String[]{ProxyAsyncConfiguration.class.getName()};
        case 2:
            return new String[]{"org.springframework.scheduling.aspectj.AspectJAsyncConfiguration"};
        default:
            return null;
        }
    }
}


     3,第三類:動態註冊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.context.annotation.AspectJAutoProxyRegistrar;
import org.springframework.context.annotation.Import;

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


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

public void registerBeanDefinitions(AnnotationMetadata importingClassMetadata, BeanDefinitionRegistry registry) {
        AopConfigUtils.registerAspectJAnnotationAutoProxyCreatorIfNecessary(registry);
        AnnotationAttributes enableAJAutoProxy = AnnotationConfigUtils.attributesFor(importingClassMetadata, EnableAspectJAutoProxy.class);
        if(enableAJAutoProxy.getBoolean("proxyTargetClass")) {
            AopConfigUtils.forceAutoProxyCreatorToUseClassProxying(registry);
        }

    }


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

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

package org.springframework.context.annotation;

import org.springframework.aop.config.AopConfigUtils;
import org.springframework.beans.factory.support.BeanDefinitionRegistry;
import org.springframework.context.annotation.AnnotationConfigUtils;
import org.springframework.context.annotation.EnableAspectJAutoProxy;
import org.springframework.context.annotation.ImportBeanDefinitionRegistrar;
import org.springframework.core.annotation.AnnotationAttributes;
import org.springframework.core.type.AnnotationMetadata;

class AspectJAutoProxyRegistrar implements ImportBeanDefinitionRegistrar {
    AspectJAutoProxyRegistrar() {
    }

    public void registerBeanDefinitions(AnnotationMetadata importingClassMetadata, BeanDefinitionRegistry registry) {
        AopConfigUtils.registerAspectJAnnotationAutoProxyCreatorIfNecessary(registry);
        AnnotationAttributes enableAJAutoProxy = AnnotationConfigUtils.attributesFor(importingClassMetadata, EnableAspectJAutoProxy.class);
        if(enableAJAutoProxy.getBoolean("proxyTargetClass")) {
            AopConfigUtils.forceAutoProxyCreatorToUseClassProxying(registry);
        }

    }
}


三:測試

        測試是開發中不可缺少的部分,單元測試只針對當前開發的類和方法進行測試,可以簡單通過模擬依賴來實現,對執行環境沒有依賴。

       spring通過Spring TestContex Framework對整合測試提供頂級支援。它不依賴於特定的測試框架,既可使用Junit,也可以使用TestNG。

       基於Maven構建的專案結構預設有關於測試的目錄:src/test/java(測試程式碼),src/test/resources(測試資源),區別於src/main/java(專案原始碼),src/main/resources(專案資源)

        Spring提供了一個SpringJUnit4ClassRunner類,它提供了Spring TestContext Framework的功能。通過@ContextConfiguration來配置ApplicationContext,通過@ActiveProfiles確定活動的profile。

        在使用了Spring測試後,我們前面例子的執行部分都可以用spring測試來檢驗功能能否正常運作。

        下面對簡單配置的Application Context和在測試中注入Bean做演示。

        1,準備

        增加Spring測試的依賴包到Maven

<!--Spring test 支援-->
        <dependency>
            <groupId>org.springframework</groupId>
            <artifactId>spring-test</artifactId>
            <version>4.1.6.RELEASE</version>
        </dependency>
        <dependency>
            <groupId>junit</groupId>
            <artifactId>junit</artifactId>
            <version>4.11</version>
        </dependency>

業務程式碼:

 在src/main/java下的原始碼:

package jack.ch3.test;

/**
 * Created by jack on 2017/7/16.
 */
public class TestBean {
    private String content;

    public TestBean(String content) {
        this.content = content;
    }

    public String getContent() {
        return content;
    }

    public void setContent(String content) {
        this.content = content;
    }
}


  配置類:

package jack.ch3.test;

import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.context.annotation.Profile;

/**
 * Created by jack on 2017/7/16.
 */
@Configuration
public class TestConfig {
    @Bean
    @Profile("dev")
    public TestBean devTestBean(){
        return new TestBean("from development profile");
    }
    @Bean
    @Profile("prod")
    public TestBean prodTestBean(){
        return new TestBean("from production profile");
    }
}


測試:

  在src/test/java下的程式碼:

package jack.ch3.test;

import org.junit.Assert;
import org.junit.Test;
import org.junit.runner.RunWith;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.test.context.ActiveProfiles;
import org.springframework.test.context.ContextConfiguration;
import org.springframework.test.context.junit4.SpringJUnit4ClassRunner;

/**
 * Created by jack on 2017/7/16.
 */
@RunWith(SpringJUnit4ClassRunner.class)//SpringJUnit4ClassRunner在JUnit環境下提供Spring TestContext Framework的功能
@ContextConfiguration(classes = {TestConfig.class}) //@ContextConfiguration用來載入配置ApplicationContext,其中classes屬性用來載入配置類
@ActiveProfiles("prod") //@ActiveProfiles用來宣告活動的profile
public class DemoBeanIntegrationTests {
    @Autowired //可使用普通的@Autowired注入Bean
    private TestBean testBean;
    @Test //測試程式碼,通過JUnit的Assert來校驗是否和預期一致
    public void prodBeanShouldInject(){
        String expected = "from production profile";
        String actual = testBean.getContent();
        Assert.assertEquals(expected,actual);
    }
}



測試結果如下:


@ActiveProfiles("prod")
改為
@ActiveProfiles("dev")

將採用開發配置的bean

到目前為止,maven中pom.xml的內容如下:

<?xml version="1.0" encoding="UTF-8"?>
<project xmlns="http://maven.apache.org/POM/4.0.0"
         xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
         xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
    <modelVersion>4.0.0</modelVersion>

    <groupId>com.jack</groupId>
    <artifactId>springstudy1</artifactId>
    <version>1.0-SNAPSHOT</version>

    <!--定義屬性-->
    <properties>
        <java.version>1.8</java.version>
    </properties>

    <!--新增依賴-->
    <dependencies>
        <!--新增spring框架依賴包-->
        <dependency>
            <groupId>org.springframework</groupId>
            <artifactId>spring-context</artifactId>
            <version>4.1.6.RELEASE</version>
        </dependency>

        <!--spring的aop支援-->
        <dependency>
            <groupId>org.springframework</groupId>
            <artifactId>spring-aop</artifactId>
            <version>4.1.6.RELEASE</version>
        </dependency>
        <!--aspectj支援-->
        <dependency>
            <groupId>org.aspectj</groupId>
            <artifactId>aspectjrt</artifactId>
            <version>1.8.5</version>
        </dependency>
        <dependency>
            <groupId>org.aspectj</groupId>
            <artifactId>aspectjweaver</artifactId>
            <version>1.8.5</version>
        </dependency>

        <!--增加commons-io可簡化檔案相關操作-->
        <dependency>
            <groupId>commons-io</groupId>
            <artifactId>commons-io</artifactId>
            <version>2.3</version>
        </dependency>

        <!--增加JSR250支援-->
        <dependency>
            <groupId>javax.annotation</groupId>
            <artifactId>jsr250-api</artifactId>
            <version>1.0</version>
        </dependency>

        <!--Spring test 支援-->
        <dependency>
            <groupId>org.springframework</groupId>
            <artifactId>spring-test</artifactId>
            <version>4.1.6.RELEASE</version>
        </dependency>
        <dependency>
            <groupId>junit</groupId>
            <artifactId>junit</artifactId>
            <version>4.11</version>
        </dependency>

    </dependencies>

    <!--新增外掛-->
    <build>
        <plugins>
            <plugin>
                <groupId>org.apache.maven.plugins</groupId>
                <artifactId>maven-compiler-plugin</artifactId>
                <version>2.3.2</version>
                <configuration>
                    <source>${java.version}</source>
                    <target>${java.version}</target>
                </configuration>
            </plugin>
        </plugins>
    </build>

</project>


相關推薦

SpringBoot5-spring高階話題-組合註解註解@Enable*註解工作原理測試

一:組合註解與元註解       從spring2開始,為了響應JDK1.5推出的註解供暖,spring開始大量加入註解來替代xml配置。spring的註解主要用來配置和注入bean,以及AOP相關的配置(@Transactional)。隨著註解的大量使用,尤其相同的多個註

spring boot組合註解註解

@Target(ElementType.TYPE) @Retention(RetentionPolicy.RUNTIME) @Documented @Configuration @ComponentScan public @interface WiselyConfiguration {

SpringSpring高階話題[email protected]***註解工作原理

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

SpringBoot4-spring高階話題-spring aware多執行緒計劃任務條件註解@Conditional

一:Spring Aware 1,點睛      spring的依賴注入的最大亮點就是你所有的Bean對Spring容器的存在是沒有意識的,即你可以將你的容器替換成別的容器,如Google Guice,這時Bean之間的耦合度很低。     但是在實際專案中,你不可避免的要

Spring高階話題-多執行緒-TaskExecutor

分析 在Spring中,通過任務執行器,也就是TaskExecutor來實現多執行緒和併發程式設計。 使用ThreadPoolTaskExecutor可實現一個基於執行緒池的TaskExecutor。 而實際開發中任務一般是非阻礙的,也就是非非同步的,所以

JavaEE開發的顛覆者:Spring Boot實戰 學習筆記4--Spring高階話題

SpringAware  可呼叫Spring所提供的資源  多執行緒 配置類 /** * 多執行緒和併發程式設計 */ @Configuration @ComponentScan("com.wisely.highlight_spring4_idea.ch3.t

SpringSpring高階話題-計劃任務[email pr

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

SpringSpring高階話題-多執行緒-TaskExecutor

分析 在Spring中,通過任務執行器,也就是TaskExecutor來實現多執行緒和併發程式設計。 使用ThreadPoolTaskExecutor可實現一個基於執行緒池的TaskExecutor。 而實際開發中任務一般是非阻礙的,也就是非非同步

USB HOST USB OTG的區別及工作原理

在SmartQ 7上面,同時存在USB HOST與 USB OTG兩個介面,我想問一下,這兩個介面有什麼區別麼?我怎麼認為HOST屬於是多餘呢? 麻煩高手解答,感激不盡!!!   零 USB背景知識 USB是一種資料通訊方式,也是一種資料匯流排,而且是最複雜的匯流排之一。&

spark核心程式設計spark基本工作原理RDD

Spark2.0筆記 spark核心程式設計,spark基本工作原理與RDD 1. Spark基本工作原理 2. RDD以及其特點 3. 什麼是Spark開發 1.Spark基本工作原理 2. RDD以及其特點 3. 什麼是Spark開發 spark核心程

Eureka的工作原理以及它ZooKeeper的區別 Eureka的工作原理以及它ZooKeeper的區別

Eureka的工作原理以及它與ZooKeeper的區別   1、Eureka 簡介: Eureka 是 Netflix 出品的用於實現服務註冊和發現的工具。 Spring Cloud 集成了 Eureka,並提供了開箱即用的支援。其中, Eureka 又可細分為 Eur

spring工作原理Spring MVC的前端控制器模式

Spring MVC的前端控制器模式 spring mvc也是依賴servlet,所以spring mvc的請求處理是從一個servlet開始,這個servlet就是DispatcherServlet。 前端控制器模式(Front Controller Pa

資料庫事務隔離級別鎖機制的實現----不是針對PostgreSQL而是普遍的原理來自網際網路有刪節

文章來自原文連結: 版權歸原作者所有,有刪節,只保留對我理解有幫助的部分。 事務隔離級別通過鎖的實現機制兩個鎖排他鎖: 被加鎖的物件只能被持有鎖的事務讀取和修改,其他事務無法在該物件上加其他鎖,也不能讀取和修改該物件。 共享鎖: 被加鎖的物件可以被持鎖事務讀取

編譯器解釋器的區別和工作原理

架構 平臺 感覺 -i 調用 詞法 繼續 python 自動 這篇教程,我們一起來了解編譯器和解釋器的工作原理,這對我們提升能力很重要。 我一直認為概念或理論知識是非常重要的,讓我們能夠將很多模糊的認知關聯起來,變得更加清楚,從而打開視野,上升到新的層次。 但是,一般來

Spring MVC的工作原理我們來看看其原始碼實現

前言   開心一刻     晚上陪老丈人吃飯,突然手機響了,我手賤按了擴音……哥們:快出來喝酒!哥幾個都在呢!我:今天不行,我現在陪老丈人吃飯呢。哥們:那你抓緊喝,我三杯白酒,把我岳父放倒了才出來的,你也快點。看著我老丈人的臉,我不知道該怎麼回了……

Spring註解Java註解小結

spa package param style 值範圍 描述 tro ret 類型 註解 Annotation 基於註解的開發,使得代碼簡潔,可讀性高,簡化的配置的同時也提高了開發的效率,尤其是SpringBoot的興起,隨著起步依賴和自動配置的完善,更是將基於註解的開發推

Spring高級話題[email protected]***註解工作原理

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

spring,mybatis事務管理配置@Transactional註解使用[轉]

exception true throws r.java 存在 隔離 enc prot 底層 spring,mybatis事務管理配置與@Transactional註解使用 概述事務管理對於企業應用來說是至關重要的,即使出現異常情況,它也可以保證數據的一致性。Sprin

Spring@Autowired註解自動裝配

arp details auto 反射機制 java -i etc str spi 1 配置文件的方法 我們編寫spring 框架的代碼時候。一直遵循是這樣一個規則:所有在spring中註入的bean 都建議定義成私有的域變量。並且要配套寫上 get 和 set方法

spring,mybatis事務管理配置@Transactional註解使用

抽象 classname 初始 for batis 時間限制 自動提交 data second spring,mybatis事務管理配置與@Transactional註解使用 概述事務管理對於企業應用來說是至關重要的,即使出現異常情況,它也可以保證數據的一致性。Spring