我有一个非托管的JPA域类。它通过new
运算符实例化。
UserAccount account = new UserAccount();
userRepository.save(account)
在我的UserAccount
课程中,我有一个beforeSave()
方法,该方法依赖于我的SecurityService
来对密码进行哈希编码。
我的问题是"如何让spring DI将安全服务注入我的实体?"。似乎AspectJ和LoadTimeWeaving是我需要的。我已经尝试过配置阵列,但我似乎无法让它们中的任何一个工作。尝试在注入的对象上调用方法时,我总是得到NullPointerException
。
UserAccount.java (这是JPA实体)
@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);
}
}
}
尝试指示春天使用AspectJ:
NitroApp.java (主要类)
@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 (配置)
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'
}
答案 0 :(得分:3)
您可以在用于实现UserAccount的类中注入Spring applicationContext。
@Autowired
private ApplicationContext applicationContext;
然后,以这种方式创建UserAccount bean:
UserAccount userAccount = applicationContext.getBean(UserAccount.class);
这样,您可以在UserAccount类中注入所需的依赖项。
答案 1 :(得分:1)
从您的配置中,我假设您在某种程度上期望Spring为您管理AOP。但是,由于您希望在非托管bean上@Autowired
,您必须通过加载时间编织或编译团队编织来进行编织。 Spring默认只支持方法级别方面。
因为加载时间编织涉及使用9.8.4中解释的javaagent(在生产场景中并不总是实用),所以我已经开始使用编译时编织。以下代码和配置适用于我。
启动配置
@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 强>
@Configurable(autowire = Autowire.BY_TYPE, dependencyCheck = true)
public class Account {
@Autowired
private SpringService service;
public void testConfigurable() {
System.out.println(service.returnHello());
}
}
<强> SpringService.java 强>
@Service
public class SpringService {
public String returnHello() {
return "Hello";
}
}
丑陋的pom.xml
<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>
以下是我所指的链接。