首页
学习
活动
专区
圈层
工具
发布
首页
学习
活动
专区
圈层
工具
MCP广场
社区首页 >问答首页 >Spring非托管bean中的依赖项注入

Spring非托管bean中的依赖项注入
EN

Stack Overflow用户
提问于 2015-06-17 11:34:05
回答 2查看 13.1K关注 0票数 5

我有一个JPA域类,它是非托管的。它通过new操作符实例化。

代码语言:javascript
运行
复制
UserAccount account = new UserAccount();
userRepository.save(account)

在我的UserAccount类中,我有一个beforeSave()方法,它依赖于我的SecurityService来对密码进行哈希编码。

我的问题是“如何使spring将安全服务注入我的实体?”看来AspectJ和LoadTimeWeaving是我所需要的。我尝试过一个配置数组,但我似乎无法让其中任何一个工作。在尝试调用注入对象上的方法时,我总是得到一个NullPointerException

UserAccount.java (这是JPA实体)

代码语言:javascript
运行
复制
@Entity
@Repository
@Configurable(autowire = Autowire.BY_TYPE)
public class UserAccount implements Serializable {

    @Transient
    @Autowired
    SecurityService securityService;

    private String passwordHash;

    @Transient
    private String password;

    public UserAccount() {
        super();
    }

    @PrePersist
    public void beforeSave() {
        if (password != null) {
            // NullPointerException Here!!!
            passwordHash = securityService.hashPassword(password);  
        }
    }
}

试图指示spring使用AspectJ:

NitroApp.java (主类)

代码语言:javascript
运行
复制
@SpringBootApplication
@EnableTransactionManagement
@EnableSpringConfigured
@PropertySources(value = {@PropertySource("classpath:application.properties")})
public class NitroApp extends SpringBootServletInitializer {


    public static void main (String[] args) {
        SpringApplication.run(NitroApp.class);
    }

}

build.gradle (配置)

代码语言:javascript
运行
复制
buildscript {
    repositories {
        mavenCentral()
        jcenter()
    }

    dependencies {
        classpath "org.springframework.boot:spring-boot-gradle-plugin:1.2.2.RELEASE"
        classpath "org.springframework:springloaded:1.2.2.RELEASE"
        classpath "org.springframework:spring-aspects:4.1.6.RELEASE"
    }
}

apply plugin: 'java'
apply plugin: 'aspectj'
apply plugin: 'application'
apply plugin: 'idea'
apply plugin: 'spring-boot'

repositories {
    jcenter()
    mavenLocal()
    mavenCentral()
}

mainClassName = 'com.noxgroup.nitro.NitroApp'
applicationName = "Nitro"

idea {
    module {
        inheritOutputDirs = false
        outputDir = file("$buildDir/classes/main/")
    }
}

dependencies {
    compile("org.springframework.boot:spring-boot-starter-web")
    compile("org.springframework.boot:spring-boot-starter-thymeleaf")
    compile("org.springframework.boot:spring-boot-starter-actuator")
    compile("org.springframework.boot:spring-boot-starter-data-jpa")
    compile("net.sourceforge.nekohtml:nekohtml:1.9.15")
    compile("commons-codec:commons-codec:1.9")
    compile("org.postgresql:postgresql:9.4-1201-jdbc41")
}

task wrapper(type: Wrapper) {
    gradleVersion = '2.3'
}
EN

回答 2

Stack Overflow用户

发布于 2015-06-17 13:56:51

您可以在用于实例化applicationContext的类中注入Spring UserAccount。

代码语言:javascript
运行
复制
@Autowired
private ApplicationContext applicationContext;

然后,以这种方式创建UserAccount bean:

代码语言:javascript
运行
复制
UserAccount userAccount = applicationContext.getBean(UserAccount.class);

这样,就可以在UserAccount类中注入所需的依赖项。

票数 6
EN

Stack Overflow用户

发布于 2015-06-18 06:11:31

从您的配置来看,我假设您希望Spring可以为您管理AOP。但是,由于您希望在非托管bean上使用@Autowired,所以您必须通过加载时编织或编译团队编织来自己进行编织。默认情况下,Spring只支持方法级方面。

因为加载时编织涉及到javaagent的使用,正如在9.8.4中解释的那样(在生产场景中并不总是实用的),所以我已经开始使用编译时编织。下面的代码和配置适用于我。

Boot Config

代码语言:javascript
运行
复制
@SpringBootApplication
@EnableSpringConfigured
public class App {
    public static void main(String[] args) {
        System.out.println("Hello World!");

        ApplicationContext ctx = SpringApplication.run(App.class, args);
        Account account = new Account();
        account.testConfigurable();
    }
}

Account.java

代码语言:javascript
运行
复制
@Configurable(autowire = Autowire.BY_TYPE, dependencyCheck = true)
public class Account {

    @Autowired
    private SpringService service;

    public void testConfigurable() {
        System.out.println(service.returnHello());
    }
}

SpringService.java

代码语言:javascript
运行
复制
@Service
public class SpringService {

    public String returnHello() {
        return "Hello";
    }

}

Ugly pom.xml

代码语言:javascript
运行
复制
<plugin>
                <groupId>org.codehaus.mojo</groupId>
                <artifactId>aspectj-maven-plugin</artifactId>
                <version>1.7</version>
                <configuration>
                    <showWeaveInfo>true</showWeaveInfo>
                    <source>1.8</source>
                    <target>1.8</target>
                    <Xlint>ignore</Xlint>
                    <complianceLevel>1.8</complianceLevel>
                    <encoding>UTF-8</encoding>
                    <verbose>false</verbose>
                    <aspectLibraries>
                        <aspectLibrary>
                            <groupId>org.springframework</groupId>
                            <artifactId>spring-aspects</artifactId>
                        </aspectLibrary>
                    </aspectLibraries>
                </configuration>
                <executions>
                    <execution>
                        <goals>
                            <goal>compile</goal>
                            <goal>test-compile</goal>
                        </goals>
                    </execution>
                </executions>
                <dependencies>
                    <dependency>
                        <groupId>org.aspectj</groupId>
                        <artifactId>aspectjrt</artifactId>
                        <version>1.8.5</version>
                    </dependency>
                    <dependency>
                        <groupId>org.aspectj</groupId>
                        <artifactId>aspectjtools</artifactId>
                        <version>1.8.5</version>
                    </dependency>
                </dependencies>
            </plugin>

以下是我参考的链接。

  1. 春季医生的9.8.1
  2. 来自这里的Maven Config。

由于我不是AOP方面的专家,所以我不确定用上述方式在普通方面配置AOP的敲击效果。讨论这里。如果加载时间编织对您来说是一个选项,那么您应该按照答案中讨论的那样继续使用这个选项。

票数 1
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/30890380

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档