Spring5參考指南:AspectJ高級編程之Configurable

遇到的問題

前面的文章咱們講到了在Spring中使用Aspect。可是Aspect的都是Spring管理的Bean。 如今有一個問題,實際工做中,咱們常常會想new一個Bean,而後在這個Bean中注入Spring管理的其餘Bean。可是new出來的bean已經脫離Spring的管控了。php

該怎麼處理呢?java

@Configurable

Spring提供了一個@Configurable的註解,能夠實現這個功能,咱們看一個例子:git

@Configurable(autowire= Autowire.BY_NAME, preConstruction = true)
public class Account {

    private static Logger log= LoggerFactory.getLogger(Account.class);

    private String name;

    @Autowired
    private BeanA beanA;

    public Account(){
        log.info("init Account");
    }

    public Object getBeanA() {
        return beanA;
    }

    public String getName() {
        return name;
    }

    public void setName(String name) {
        this.name = name;
    }
}
複製代碼

這裏定義了一個Account類,它裏面有依賴的BeanA,咱們想在new Account()的時候, 直接使用Spring注入的BeanA。github

preConstruction = true 表示依賴的Bean在構造函數調用以前就被注入了。spring

autowire= Autowire.BY_NAME 表示依賴的Bean是按名字來自動裝配。固然也能夠使用autowire= Autowire.BY_TYPE,按類型來裝配。apache

同時咱們須要開啓SpringConfig支持:app

@Configuration
@EnableSpringConfigured
public class AppConfig {
}
複製代碼

最後看下咱們怎麼調用:maven

public class ConfigurableApp {

    private static Logger log= LoggerFactory.getLogger(ConfigurableApp.class);

    public static void main(String[] args) {
        ApplicationContext applicationContext=new ClassPathXmlApplicationContext("bean-config.xml");

        Account accountA=new Account();
        log.info(accountA.getBeanA().toString());

    }
}
複製代碼

輸出結果以下:函數

07:37:27.917 [main] INFO com.flydean.beans.Account - init Account
07:37:27.917 [main] INFO com.flydean.ConfigurableApp - com.flydean.beans.BeanA@54c5a2ff
複製代碼

能夠看到雖然Account是new出來的,可是BeanA依然被注入到實例中。ui

原理

單獨使用@Configurable沒有任何做用。

Spring-Aspects.jar中的AnnotationBeanConfigurerAspect,纔是讓@Configurable起做用的根本。本質上,aspect是,「從用@Configurable註解的類型的新對象的初始化返回後,根據註解的屬性使用spring配置新建立的對象」。在此上下文中,「初始化」是指新實例化的對象(例如,用new運算符實例化的對象)以及正在進行反序列化的可序列化對象(例如,經過 readResolve())。

重要配置

下面是最最重要的pom配置了,這裏我使用了aspectj-maven-plugin 這個插件來對spring-aspects.jar進行編織。 以下所示:

<?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">
    <parent>
        <artifactId>spring5-core-workshop</artifactId>
        <groupId>com.flydean</groupId>
        <version>1.0-SNAPSHOT</version>
    </parent>
    <modelVersion>4.0.0</modelVersion>

    <artifactId>aop-advanced</artifactId>
    <dependencies>
        <dependency>
            <groupId>org.springframework</groupId>
            <artifactId>spring-tx</artifactId>
            <version>5.1.3.RELEASE</version>
        </dependency>

        <dependency>
            <groupId>org.springframework</groupId>
            <artifactId>spring-aspects</artifactId>
            <version>5.1.3.RELEASE</version>
        </dependency>

    </dependencies>

    <build>
        <!-- To define the plugin version in your parent POM -->
        <pluginManagement>
            <plugins>
                <plugin>
                    <groupId>org.codehaus.mojo</groupId>
                    <artifactId>aspectj-maven-plugin</artifactId>
                    <version>1.11</version>
                </plugin>
            </plugins>
        </pluginManagement>
        <!-- To use the plugin goals in your POM or parent POM -->
        <plugins>
            <plugin>
                <groupId>org.codehaus.mojo</groupId>
                <artifactId>aspectj-maven-plugin</artifactId>

                <configuration>
                    <complianceLevel>1.8</complianceLevel>
                    <source>1.8</source>
                    <target>1.8</target>
                    <outxml>true</outxml>
                    <verbose>true</verbose>
                    <showWeaveInfo>true</showWeaveInfo>
                    <aspectLibraries>
                        <aspectLibrary>
                            <groupId>org.springframework</groupId>
                            <artifactId>spring-aspects</artifactId>
                        </aspectLibrary>
                    </aspectLibraries>
                </configuration>


                <executions>
                    <execution>
                        <goals>
                            <goal>compile</goal>       <!-- use this goal to weave all your main classes -->
                            <goal>test-compile</goal>  <!-- use this goal to weave all your test classes -->
                        </goals>
                    </execution>
                </executions>
            </plugin>
        </plugins>
    </build>

</project>
複製代碼

本文的例子能夠參考aop-advanced

更多教程請參考 flydean的博客

相關文章
相關標籤/搜索