@Configurable


AnnotationBeanConfigurerAspect

AnnotationBeanConfigurerAspect是一個AspectJ切面,使用AspectJ語言定義。
通過上下文獲取該切面后,調用其實例方法configureBean(),可對一個使用new關鍵字創建的對象進行配置,實現自動連線。

AnnotationBeanConfigureAspect本身需要由Spring進行配置(以便獲得用於配置新對象的bean工廠的引用)。@EnableSpringConfigured注解專門實現該需求。

該切面屬於制品spring-aspects

dependencies {
    implementation 'org.jetbrains.kotlin:kotlin-stdlib'
    implementation 'org.springframework:spring-context:5.2.0.RELEASE'
    implementation 'org.springframework:spring-aspects:5.2.0.RELEASE'
}

configureBean():

package bean

import org.junit.jupiter.api.Test
import org.junit.jupiter.api.extension.ExtendWith
import org.springframework.beans.factory.annotation.Autowired
import org.springframework.beans.factory.annotation.Configurable
import org.springframework.beans.factory.aspectj.AnnotationBeanConfigurerAspect
import org.springframework.context.ApplicationContext
import org.springframework.context.annotation.ComponentScan
import org.springframework.stereotype.Component
import org.springframework.test.context.junit.jupiter.SpringExtension
import org.springframework.test.context.junit.jupiter.SpringJUnitConfig

@Component
@Configurable(preConstruction = true)
open class A {
    @Autowired
    open var ctx: ApplicationContext? = null

    open fun foo() {
        println(ctx)
    }
}

@ExtendWith(SpringExtension::class)
@SpringJUnitConfig(ConfigurableTest::class)
@ComponentScan
@org.springframework.context.annotation.aspectj.EnableSpringConfigured
open class ConfigurableTest {
    @Autowired lateinit var ctx: ApplicationContext
    @Test fun main() {
        A().foo() // null
        ctx.getBean(A::class.java).foo() // not null

        val aspect = ctx.getBean(AnnotationBeanConfigurerAspect::class.java)
        val bean = A()
        bean.foo() // null
        aspect.configureBean(bean)
        bean.foo() // not null
    }
}

加載時編織

要啟用Spring框架的LTW支持,你需要配置一個LoadTimeWeaver,通常通過使用@EnableLoadTimeWeaving注解完成。

@Configuration
@PropertySource("classpath:application.properties")
@ComponentScan
@org.springframework.context.annotation.aspectj.EnableSpringConfigured // AnnotationBeanConfigureAspect本身需要由Spring進行配置(以便獲得用於配置新對象的bean工廠的引用)
//@EnableLoadTimeWeaving(aspectjWeaving = EnableLoadTimeWeaving.AspectJWeaving.ENABLED) // 要啟用Spring框架的LTW支持,你需要配置一個LoadTimeWeaver,通常通過使用@EnableLoadTimeWeaving注解完成
//@EnableLoadTimeWeaving(aspectjWeaving = EnableLoadTimeWeaving.AspectJWeaving.DISABLED)
@EnableLoadTimeWeaving(aspectjWeaving = EnableLoadTimeWeaving.AspectJWeaving.AUTODETECT) // 自動檢測META-INF/aop.xml配置文件是否存在
open class JavaConfig : LoadTimeWeavingConfigurer {
    // Implement LoadTimeWeavingConfigurer is optional. In default, DefaultContextLoadTimeWeaver will active.
    override fun getLoadTimeWeaver(): LoadTimeWeaver {
        return InstrumentationLoadTimeWeaver().apply {
            println("inject -> $this")
        }
    }
}

加載時編織需要修改jvm選項,設置代理為spring-instrument,可在Gradle腳本中設置:

dependencies {
    // AOP
    // https://mvnrepository.com/artifact/org.aspectj/aspectjrt
    implementation group: 'org.aspectj', name: 'aspectjrt', version: '1.9.6'
    // https://mvnrepository.com/artifact/org.aspectj/aspectjweaver
    implementation group: 'org.aspectj', name: 'aspectjweaver', version: '1.9.6'
    // Spring-instrument
    runtimeOnly 'org.springframework:spring-instrument:5.2.0.RELEASE'
}

test {
    // Setup the Java agent to Spring-instrument
    def file_spring_instrument = sourceSets.test.runtimeClasspath.find { it.name.matches("spring-instrument-.*\\.jar") }
    jvmArgs "-javaagent:$file_spring_instrument"

    useJUnitPlatform()
}

@See: https://docs.gradle.org/current/userguide/building_java_projects.html#sec:feature_preview

META-INF/aop.xml

META-INF/aop.xml定義需要掃描、配置的類,格式如下:

<!DOCTYPE aspectj PUBLIC "-//AspectJ//DTD//EN" "https://www.eclipse.org/aspectj/dtd/aspectj.dtd">
<aspectj>

    <weaver>
        <!-- only weave classes in our application-specific packages -->
        <include within="bean.*"/>
    </weaver>

</aspectj>

END


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM