欧美bbbwbbbw肥妇,免费乱码人妻系列日韩,一级黄片

Spring中IOC和AOP的核心組成架構(gòu)詳解

 更新時(shí)間:2023年08月25日 10:13:42   作者:摳腳的大灰狼  
這篇文章主要介紹了Spring中IOC和AOP的核心組成架構(gòu)詳解,本文是對(duì)Spring的2大核心功能——IoC和AOP 的總結(jié)提煉,并增加了環(huán)境profile和條件化bean的內(nèi)容,篇幅較短,更像是一個(gè)大綱,或者思維導(dǎo)圖,需要的朋友可以參考下

IoC配置

注冊(cè)bean

XML

<bean> 標(biāo)簽

屬性

  • id
  • class
  • init-method
  • destroy-method
  • scope

子標(biāo)簽

  • <constructor-arg>:構(gòu)造器注入 --> c命名空間注入
  • <property>:set方法注入 --> p命名空間注入

注解

  • @Component:注解在類(lèi)上,配合自動(dòng)掃描(@ComponentScan),完成注冊(cè)
    • @Controller
    • @Service
    • @Repository
  • @Bean:注解在方法上,方法的返回值對(duì)象會(huì)注冊(cè)到Spring容器(常用于創(chuàng)建第三方j(luò)ar包中的類(lèi)對(duì)象)。這些被@Bean標(biāo)注的方法需要放到Spring配置類(lèi)當(dāng)中(被@Configuration標(biāo)注的類(lèi))

其他注解

  • @ComponentScan:?jiǎn)⒂米詣?dòng)掃描,掃描指定包下帶有@Component注解的類(lèi)(對(duì)應(yīng)XML中的<context:component-scan>)
  • @Configuration:將某個(gè)類(lèi)標(biāo)記為配置類(lèi)
  • @Import:組合多個(gè)配置類(lèi)
  • @Scope:指定bean的作用范圍。與@Component或@Bean組合使用。值是字符串,可以用ConfigurableBeanFactory中的常量,或WebApplicationContext中的常量
  • @PostContruct:自定義初始化函數(shù),約等XML的init-method。(也可通過(guò)InitializingBean接口實(shí)現(xiàn))
  • @PreDestroy:自定義銷(xiāo)毀函數(shù),約等于XML的destroy-method。(也可通過(guò)DisposableBean接口實(shí)現(xiàn))

裝配bean

@Autowired

屬于Spring,按類(lèi)型注入, required 屬性默認(rèn)為 true 。由Spring中的 AutowiredAnnotationBeanPostProcessor 進(jìn)行處理。

注:帶 @Autowired 注解的方法,會(huì)被Spring自動(dòng)調(diào)用。

@Resource

屬于JavaEE(JSR250),當(dāng)指定了 name 屬性時(shí),按照名稱( bean 的 id )注入;否則,按照類(lèi)型注入

@Inject

屬于JavaEE(JSR330),需導(dǎo)入額外的 jar 包,按照類(lèi)型注入

<dependency>
   <groupId>javax.inject</groupId>
   <artifactId>javax.inject</artifactId>
   <version>1</version>
</dependency>

@Value

用來(lái)注入基本類(lèi)型和 String 類(lèi)型的值。

可以用 ${} ,來(lái)獲取 properties 文件中的屬性。( properties 文件要加載到Spring中)

關(guān)于把 properties 文件加載到Spring

  • 創(chuàng)建一個(gè) PropertyPlaceholderConfigurer 對(duì)象到Spring容器中,設(shè)置 location 的值為 properties 文件的路徑

可通過(guò) <context:property-placeholder> 標(biāo)簽進(jìn)行簡(jiǎn)化

  • @PropertySource

用 @PropertySource 結(jié)合 @Component 或者 @Configuration

注意: properties 文件中的屬性,會(huì)被加載到Spring的Environment對(duì)象中,多個(gè) properties 中的同名屬性,會(huì)發(fā)生覆蓋

高級(jí)裝配

環(huán)境與Profile

@Profile 與 @Configuration 或 @Component , @Bean 等結(jié)合使用。

可以控制僅在某一 profile 下激活對(duì)應(yīng)的類(lèi)。如下面的配置類(lèi)僅在 dev 環(huán)境下生效

@Profile("dev")
@Configuration
public class DevConfig {
    @Bean
    public PetService petService() {
        return new PetService();
    }
}

如何指定當(dāng)前激活的 profile ?

依賴于2個(gè)獨(dú)立屬性: spring.profiles.active 和 spring.profiles.default 。

若設(shè)置前者,則根據(jù)前者來(lái)確定;若沒(méi)設(shè)置前者,則根據(jù)后者來(lái)確定。若2者都未指定,則只會(huì)激活那些沒(méi)有定義在某一 profile 下的類(lèi)

有多種方式來(lái)設(shè)置這2個(gè)屬性

  • 作為環(huán)境變量(如在maven的profile標(biāo)簽下配置上述2個(gè)屬性,并在maven打包時(shí)用 -P 參數(shù)指定maven的profile)
<profiles>
        <!-- 開(kāi)發(fā)環(huán)境 -->
        <profile>
            <id>dev</id>
            <properties>
                <spring.profiles.active>dev</spring.profiles.active>
            </properties>
            <activation>
                <activeByDefault>true</activeByDefault>
            </activation>
        </profile>
        <!-- 生產(chǎn)環(huán)境 -->
        <profile>
            <id>prod</id>
            <properties>
                <spring.profiles.active>prod</spring.profiles.active>
            </properties>
        </profile>
    </profiles>
  • 作為Web應(yīng)用的上下文參數(shù)(SpringMvc)
<!-- web,xml 中 -->
<!-- 省略其他部分 -->
<context-param>
    <param-name>spring.profiles.active</param-name>
    <param-value>dev</param-value>
</context-param>

作為DispatcherServlet的啟動(dòng)參數(shù)(SpringMvc)

  • 在 web.xml 中配置 servlet 時(shí),通過(guò) <init-param> 指定
  • 集成測(cè)試時(shí),在測(cè)試類(lèi)上用 @ActiveProfiles 注解進(jìn)行指定
  • 通過(guò)JVM啟動(dòng)參數(shù) -Dspring.profiles.active=dev

條件化bean

在滿足某些條件時(shí),才創(chuàng)建某些 bean 。通過(guò) @Conditional 注解和 Condition 接口實(shí)現(xiàn),示例如下

package org.demo.pet.conditional;
public class MagicBean { }
package org.demo.pet.conditional;
import org.springframework.context.annotation.Condition;
import org.springframework.context.annotation.ConditionContext;
import org.springframework.core.type.AnnotatedTypeMetadata;
public class MagicCondition implements Condition {
	/**
	 * 若 matches 方法返回 true, 則表示條件滿足, 會(huì)創(chuàng)建對(duì)應(yīng)的bean; 若返回 false, 則不會(huì)創(chuàng)建對(duì)應(yīng)bean
	 * **/
	@Override
	public boolean matches(ConditionContext context, AnnotatedTypeMetadata metadata) {
        // 當(dāng)Spring的Environment中存在名為 magic 的屬性, 才認(rèn)為滿足條件
		return context.getEnvironment().containsProperty("magic");
	}
}
package org.demo.pet.conditional;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Conditional;
import org.springframework.context.annotation.Configuration;
@Configuration
public class ConditionalConfig {
	@Conditional(MagicCondition.class)
	@Bean
	public MagicBean magicBean() {
		return new MagicBean();
	}
}

測(cè)試

package org.demo.test.condition;
import org.demo.pet.conditional.ConditionalConfig;
import org.demo.pet.conditional.MagicBean;
import org.junit.Test;
import org.junit.runner.RunWith;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.test.context.ContextConfiguration;
import org.springframework.test.context.junit4.SpringJUnit4ClassRunner;
@RunWith(SpringJUnit4ClassRunner.class)
@ContextConfiguration(classes = ConditionalConfig.class)
public class ConditionTest {
	@Autowired(required = false)
	private MagicBean magicBean;
	@Test
	public void test() {
		System.out.println(magicBean == null);
	}
}

由于 magic 屬性在Spring中不存在,所以上面的 magicBean == null 表達(dá)式值為 true ,如下

若添加 magic 屬性,則 MagicBean 會(huì)被創(chuàng)建

# magic.properties
magic=HarryPotter
package org.demo.pet.conditional;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Conditional;
import org.springframework.context.annotation.Configuration;
import org.springframework.context.annotation.PropertySource;
@Configuration
@PropertySource("classpath:magic.properties")
public class ConditionalConfig {
	@Conditional(MagicCondition.class)
	@Bean
	public MagicBean magicBean() {
		return new MagicBean();
	}
}

再次運(yùn)行測(cè)試, magicBean == null 表達(dá)式值為 false

Condition 接口中的 matches 方法提供了2個(gè)參數(shù): ConditionContext 和 AnnotatedTypedMetadata

通過(guò) ConditionContext

  • 借助getRegistry方法,可以檢查bean的定義
  • 借助getBeanFactory方法,可以檢查bean是否存在,檢查bean的屬性等
  • 借助getEnvironment方法,檢查環(huán)境變量等

通過(guò) AnnotatedTypedMetadata ,可以檢查注解的情況

Spring自帶的的 @Profile 注解,也是通過(guò) @Conditional 這種方式實(shí)現(xiàn)的

處理歧義性

依賴注入時(shí),當(dāng)同一個(gè)類(lèi)型,有多個(gè)候選 bean 時(shí),如何解決?

  • 將其中一個(gè) bean 標(biāo)記為首選

使用 @Primary 注解( @Primary 與 @Component 搭配,或 @Primary 與 @Bean 搭配)(只能有一個(gè)首選 bean ,當(dāng)出現(xiàn)多個(gè)首選 bean 時(shí),Spring仍然不知道該注入哪一個(gè))

  • 使用限定符

@Qualifier 是主要的限定符使用方式,可以搭配 @Autowired ,或者 @Inject 。

一個(gè) bean 的限定符,默認(rèn)情況下是這個(gè) bean 的 id ;當(dāng)然,也可以為 bean 設(shè)置自定義的限定符,如

@Component
@Qualifier("cold")  // 也可以與@Bean注解結(jié)合使用
public class IceCream implements Dessert {
}

一個(gè) bean 可以有多個(gè)限定符,不同的 bean 可以有相同的限定符。當(dāng)依賴注入時(shí),如果通過(guò)一個(gè)限定符仍然能匹配多個(gè)候選者,那么可以指定更多的限定符,如

@Component
@Qualifier("cold")
@Qualifier("creamy")
public class IceCream implements Dessert {
}
@Component
@Qualifier("cold")
public class Popsicle implements Dessert {
}
@Autowired
@Qualifier("cold")
@Qualifier("creamy")
public void setDessert(Dessert dessert) {}

注:Java 8 之前不允許出現(xiàn)重復(fù)注解,Java 8以后,當(dāng)這個(gè)注解被標(biāo)記為 @Repeatable 時(shí),可以重復(fù)。

可以創(chuàng)建自定義的限定符注解來(lái)解決這個(gè)問(wèn)題,如

@Target({ElementType.FIELD, ElementType.METHOD, ElementType.PARAMETER, ElementType.TYPE, ElementType.ANNOTATION_TYPE})
@Retention(RetentionPolicy.RUNTIME)
@Qualifier
public @interface Cold {
}
@Target({ElementType.FIELD, ElementType.METHOD, ElementType.PARAMETER, ElementType.TYPE, ElementType.ANNOTATION_TYPE})
@Retention(RetentionPolicy.RUNTIME)
@Qualifier
public @interface Creamy {
}

AOP配置

術(shù)語(yǔ)

  • JoinPoint:連接點(diǎn)。共3種:方法級(jí)別,字段級(jí)別,構(gòu)造器級(jí)別。SpringAop僅支持方法級(jí)別,AspectJ支持全部3種。
  • PointCut:切入點(diǎn)。連接點(diǎn)的匹配條件。
  • Advice:通知。根據(jù)執(zhí)行時(shí)機(jī),分為前置通知,后置通知,環(huán)繞通知,等。
  • Aspect:切面。等于切入點(diǎn)+通知
  • Weaving:織入。分為靜態(tài)織入,動(dòng)態(tài)織入。SpringAop采用動(dòng)態(tài)織入(動(dòng)態(tài)代理),AspectJ采用靜態(tài)織入。
  • Target:目標(biāo)對(duì)象。即被AOP攔截的原始對(duì)象。
  • Proxy:代理對(duì)象。
  • Introduction:引介??蓪?duì)目標(biāo)對(duì)象添加新的方法。

使用 XML

<aop:config>
        <aop:pointcut id="pointcut" expression="within(org..*.PetService)"/>  <!-- 切入點(diǎn) -->
        <aop:aspect ref="xmlAspect"> <!-- 切面, 使用id為xmlAspect的對(duì)象 -->
            <aop:before method="log" pointcut-ref="pointcut"/>  <!-- 使用切面對(duì)象中的log方法, 對(duì)切入點(diǎn)應(yīng)用前置通知 -->
        </aop:aspect>
</aop:config>

注解

  • 定義切面
    • @Aspect @Component
    • 切面中定義切入點(diǎn)和通知

切入點(diǎn)

  • @Pointcut :定義一個(gè)切入點(diǎn),在其他地方可引用。

切入點(diǎn)表達(dá)式

  • execution:匹配方法。格式為[修飾符] 返回值 包名.類(lèi)名.方法名(形參列表) [異常]
  • within:匹配類(lèi)
  • args:匹配參數(shù)
  • this:匹配代理對(duì)象(可指定為接口,會(huì)攔截到接口實(shí)現(xiàn)類(lèi))
  • target:匹配目標(biāo)對(duì)象
  • bean:匹配Spring容器中的bean
  • @annotation:匹配帶某一注解的方法
  • @within:匹配帶某一注解的類(lèi)(要求注解的RetentionPolicy至少為CLASS級(jí)別)
  • @target:匹配帶某一注解的類(lèi)(要求注解的RetentionPolicy至少為RUNTIME)
  • @args:匹配帶某一注解的參數(shù)

切入點(diǎn)表達(dá)式中可以用通配符和邏輯運(yùn)算符

通配符

  • *:匹配任意數(shù)量字符
  • ..:匹配多級(jí)包名, 或任意參數(shù)
  • +:匹配指定類(lèi)及其子類(lèi)

邏輯運(yùn)算符: && , || , ! (在XML中需要換成 and , or , not )

通知

  • @Before
  • @After:無(wú)論目標(biāo)對(duì)象的方法是否執(zhí)行成功,都會(huì)執(zhí)行通知。
  • @Around

環(huán)繞通知,最強(qiáng)大的通知。其方法形參中必須包含一個(gè) ProceedingJoinPoint 對(duì)象,可以通過(guò)這個(gè)對(duì)象上的 getArgs 方法獲取被攔截的目標(biāo)對(duì)象的方法入?yún)?,通過(guò) proceed 方法執(zhí)行原目標(biāo)對(duì)象的方法。

  • @AfterReturning :僅在目標(biāo)對(duì)象的方法執(zhí)行成功后,執(zhí)行通知。
  • @AfterThrowing :僅在目標(biāo)對(duì)象的方法執(zhí)行拋出異常時(shí),執(zhí)行通知。
  • 開(kāi)啟AOP自動(dòng)代理

@EnableAspectJAutoProxy 或者 <aop:aspectj-autoproxy/>

事務(wù)支持

3大核心接口:PlatformTransactionManager,TransactionDefinition,TransactionStatus

需要

  • 一個(gè)PlatformTransactionManager對(duì)象(這個(gè)對(duì)象需要一個(gè)DataSource對(duì)象)
  • 事務(wù)的AOP配置

通常使用Mybatis時(shí),采用spring-jdbc包下的DataSourceTransactionManager即可

使用

  • 需要導(dǎo)入spring-tx依賴,通常還需要spring-jdbc。
  • 當(dāng)PlatformTransactionManager對(duì)象準(zhǔn)備就緒后,進(jìn)行事務(wù)的AOP配置即可,如下

XML

  • <tx:advice>配置需要進(jìn)行事務(wù)管理的方法。
  • <aop:config>配置AOP。其子標(biāo)簽使用<aop:advisor>。

注解

  • @Transactional:在需要事務(wù)支持的方法上,打上該注解,并配置事務(wù)隔離級(jí)別,傳播行為等
  • 開(kāi)啟事務(wù)事務(wù)管理

@EnableTransactionManagement或者<tx:annotation-driven>

到此這篇關(guān)于Spring中核心功能IOC和AOP的詳細(xì)解讀的文章就介紹到這了,更多相關(guān)Spring中的IOC和AOP內(nèi)容請(qǐng)搜索腳本之家以前的文章或繼續(xù)瀏覽下面的相關(guān)文章希望大家以后多多支持腳本之家!

相關(guān)文章

  • 詳解Java分布式系統(tǒng)中一致性哈希算法

    詳解Java分布式系統(tǒng)中一致性哈希算法

    這篇文章主要介紹了Java分布式系統(tǒng)中一致性哈希算法,對(duì)算法感興趣的同學(xué),可以參考下
    2021-04-04
  • 在spring-boot工程中添加spring mvc攔截器

    在spring-boot工程中添加spring mvc攔截器

    這篇文章主要介紹了在spring-boot工程中添加spring mvc攔截器,Spring MVC的攔截器(Interceptor)不是Filter,同樣可以實(shí)現(xiàn)請(qǐng)求的預(yù)處理、后處理。,需要的朋友可以參考下
    2019-06-06
  • Java實(shí)現(xiàn)一個(gè)順序表的完整代碼

    Java實(shí)現(xiàn)一個(gè)順序表的完整代碼

    順序表是用一段物理地址連續(xù)的存儲(chǔ)單元依次存儲(chǔ)數(shù)據(jù)元素的線性結(jié)構(gòu),一般采用數(shù)組存儲(chǔ)。在數(shù)組上完成數(shù)據(jù)的增刪減改。順序表的底層是一個(gè)數(shù)組
    2021-04-04
  • Java?遠(yuǎn)程調(diào)用失敗重試的操作方法

    Java?遠(yuǎn)程調(diào)用失敗重試的操作方法

    這篇文章主要介紹了Java?遠(yuǎn)程調(diào)用失敗重試的操作方法,今天給大家介紹了一下?Spring??的?@Retryable?注解使用,并通過(guò)幾個(gè) demo 來(lái)帶大家編寫(xiě)了自己重試攔截器以及回滾方法,需要的朋友可以參考下
    2022-09-09
  • Java程序進(jìn)程起來(lái)了但是不打印日志的原因分析

    Java程序進(jìn)程起來(lái)了但是不打印日志的原因分析

    這篇文章主要介紹了Java程序進(jìn)程起來(lái)了但是不打印日志的原因分析,具有很好的參考價(jià)值,希望對(duì)大家有所幫助,如有錯(cuò)誤或未考慮完全的地方,望不吝賜教
    2025-04-04
  • 如何只返回實(shí)體類(lèi)中的部分字段問(wèn)題

    如何只返回實(shí)體類(lèi)中的部分字段問(wèn)題

    這篇文章主要介紹了如何只返回實(shí)體類(lèi)中的部分字段問(wèn)題,具有很好的參考價(jià)值,希望對(duì)大家有所幫助。如有錯(cuò)誤或未考慮完全的地方,望不吝賜教
    2023-05-05
  • 一文詳解Spring?security框架的使用

    一文詳解Spring?security框架的使用

    Spring?Security是一個(gè)基于Spring框架的安全認(rèn)證和授權(quán)框架,它提供了一套全面的安全解決方案,可以在Web應(yīng)用、移動(dòng)應(yīng)用和Web服務(wù)等不同場(chǎng)景下使用。本文就來(lái)詳細(xì)聊聊它的使用吧
    2023-03-03
  • MyBatis連接池的深入和動(dòng)態(tài)SQL詳解

    MyBatis連接池的深入和動(dòng)態(tài)SQL詳解

    這篇文章主要介紹了MyBatis連接池的深入和動(dòng)態(tài)SQL詳解,具有很好的參考價(jià)值,希望對(duì)大家有所幫助。如有錯(cuò)誤或未考慮完全的地方,望不吝賜教
    2022-02-02
  • 詳解在Java的Struts2框架中配置Action的方法

    詳解在Java的Struts2框架中配置Action的方法

    這篇文章主要介紹了詳解在Java的Struts2框架中配置Action的方法,講解了包括struts.xml中的action配置及基于注解方式Action配置的兩個(gè)方式,需要的朋友可以參考下
    2016-03-03
  • spring boot使用thymeleaf模板的方法詳解

    spring boot使用thymeleaf模板的方法詳解

    thymeleaf 是新一代的模板引擎,在spring4.0中推薦使用thymeleaf來(lái)做前端模版引擎。下面這篇文章主要給大家介紹了關(guān)于spring boot使用thymeleaf模板的方法,文中通過(guò)示例代碼介紹的非常詳細(xì),需要的朋友們下面來(lái)一起看看吧。
    2017-07-07

最新評(píng)論