Hello. i am a developer in asia.
i can not speak english.
so with the help of google translator writes a question. please understand.
Spring data-JPA is the Auditing feature. it operates transparently by AOP are explained.
Spring data-JPA AuditingEntityListener of the audit information has been processed.
AuditingEntityListener is AuditorAware need. and @Configurable is declared.
after you create AuditingEntityListener is AuditorAware injected by spring.
I've always understood.
@Configurable in the AspectJ LTW (Load-time weaving) must be present.
and LTW should use -javaagent option or should use LoadTimeWeaver implementation
( ex. TomcatInstrumentableClassLoader )
but as to write JUnit Test Case. performed without any problems.
Code:- Domain.java @Entity public class Domain extends AbstractAuditable<User, Long> { ... } - User.java @Entity public class User { ... } - DomainRepository.java public interface DomainRepository extends JpaRepository<Domain, Long> { } - UserRepository.java public interface UserRepository extends JpaRepository<User, Long> { } - DefaultAuditorAware.java public class DefaultAuditorAware implements AuditorAware<User> { @Autowired UserRepository userRepository; @Override public User getCurrentAuditor() { return userRepository.findAll().get(0); } } - orm.xml <persistence-unit-metadata> <persistence-unit-defaults> <entity-listeners> <entity-listener class="org.springframework.data.jpa.domain.support.AuditingEntityListener" /> </entity-listeners> </persistence-unit-defaults> </persistence-unit-metadata> - testPersistence-context.xml <?xml version="1.0" encoding="UTF-8"?> <beans xmlns="http://www.springframework.org/schema/beans" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:jdbc="http://www.springframework.org/schema/jdbc" xmlns:tx="http://www.springframework.org/schema/tx" xsi:schemaLocation="..."> <bean id="entityManagerFactory" class="org.springframework.orm.jpa.LocalContainerEntityManagerFactoryBean"> <property name="dataSource" ref="dataSource" /> <property name="packagesToScan" value="test.auditing"/> <property name="mappingResources"> <value>META-INF/orm.xml</value> </property> <property name="jpaVendorAdapter"> <bean class="org.springframework.orm.jpa.vendor.HibernateJpaVendorAdapter" /> </property> <property name="jpaProperties"> <props> <prop key="hibernate.dialect">org.hibernate.dialect.HSQLDialect</prop> <prop key="hibernate.hbm2ddl.auto">create-drop</prop> <prop key="hibernate.show_sql">false</prop> <prop key="hibernate.format_sql">false</prop> </props> </property> </bean> <bean id="transactionManager" class="org.springframework.orm.jpa.JpaTransactionManager"> <property name="entityManagerFactory" ref="entityManagerFactory"/> </bean> <jdbc:embedded-database id="dataSource" type="HSQL"/> </beans> - testRepository-context.xml <?xml version="1.0" encoding="UTF-8"?> <beans xmlns="http://www.springframework.org/schema/beans" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:jpa="http://www.springframework.org/schema/data/jpa" xsi:schemaLocation="..."> <bean id="auditorAware" class="test.auditing.DefaultAuditorAware" /> <jpa:repositories base-package="test.auditing" entity-manager-factory-ref="entityManagerFactory" transaction-manager-ref="transactionManager" /> <jpa:auditing auditor-aware-ref="auditorAware" /> </beans>without javaagent How does it work?Code:@RunWith(SpringJUnit4ClassRunner.class) @ContextConfiguration(locations={"/testPersistence-context.xml", "/testRepository-context.xml"}) public class NamespaceConfigAuditingTest { @Autowired UserRepository userRepository; @Autowired DomainRepository domainRepository; @Test public void testDomainAuditing() { User user = userRepository.saveAndFlush(new User("default")); Domain domain = domainRepository.save(new Domain()); assertThat(domain.getCreatedBy(), is(user)); } }
and <jpa:auditing/> namespace should be able to track. i found AuditingBeanDefinitionParser.
modify the test code. performed without any problems.
the revised code is as follows.
one more test code has been modified.Code:- AuditingBeanDefinitionRegistryPostProcessor.java public class AuditingBeanDefinitionRegistryPostProcessor implements BeanDefinitionRegistryPostProcessor { static final String AUDITING_ENTITY_LISTENER_CLASS_NAME = "org.springframework.data.jpa.domain.support.AuditingEntityListener"; static final String AUDITING_BFPP_CLASS_NAME = "org.springframework.data.jpa.domain.support.AuditingBeanFactoryPostProcessor"; static final String BEAN_CONFIGURER_ASPECT_BEAN_NAME = "org.springframework.context.config.internalBeanConfigurerAspect"; static final String BEAN_CONFIGURER_ASPECT_CLASS_NAME = "org.springframework.beans.factory.aspectj.AnnotationBeanConfigurerAspect"; @Override public void postProcessBeanFactory(ConfigurableListableBeanFactory beanFactory) throws BeansException { } @Override public void postProcessBeanDefinitionRegistry(BeanDefinitionRegistry registry) throws BeansException { if (!registry.containsBeanDefinition(BEAN_CONFIGURER_ASPECT_BEAN_NAME)) { RootBeanDefinition def = new RootBeanDefinition(); def.setBeanClassName(BEAN_CONFIGURER_ASPECT_CLASS_NAME); def.setFactoryMethodName("aspectOf"); def.setRole(BeanDefinition.ROLE_INFRASTRUCTURE); BeanDefinitionReaderUtils.registerBeanDefinition(new BeanComponentDefinition(def, BEAN_CONFIGURER_ASPECT_BEAN_NAME), registry); } BeanDefinitionBuilder builder = rootBeanDefinition(AUDITING_ENTITY_LISTENER_CLASS_NAME); builder.setScope("prototype"); builder.addPropertyValue("auditorAware", createLazyInitTargetSourceBeanDefinition("auditorAware")); AbstractBeanDefinition defAel = builder.getRawBeanDefinition(); BeanDefinitionReaderUtils.registerBeanDefinition(new BeanComponentDefinition(defAel, AUDITING_ENTITY_LISTENER_CLASS_NAME), registry); RootBeanDefinition defAbepp = new RootBeanDefinition(); defAbepp.setBeanClassName(AUDITING_BFPP_CLASS_NAME); BeanDefinitionReaderUtils.registerBeanDefinition(new BeanComponentDefinition(defAbepp, AUDITING_BFPP_CLASS_NAME), registry); } private BeanDefinition createLazyInitTargetSourceBeanDefinition(String auditorAwareRef) { BeanDefinitionBuilder targetSourceBuilder = rootBeanDefinition(LazyInitTargetSource.class); targetSourceBuilder.addPropertyValue("targetBeanName", auditorAwareRef); BeanDefinitionBuilder builder = rootBeanDefinition(ProxyFactoryBean.class); builder.addPropertyValue("targetSource", targetSourceBuilder.getBeanDefinition()); return builder.getBeanDefinition(); } } - testRepository-context.xml <?xml version="1.0" encoding="UTF-8"?> <beans xmlns="http://www.springframework.org/schema/beans" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:jpa="http://www.springframework.org/schema/data/jpa" xsi:schemaLocation="..."> <bean id="auditorAware" class="test.auditing.DefaultAuditorAware" /> <jpa:repositories base-package="test.auditing" entity-manager-factory-ref="entityManagerFactory" transaction-manager-ref="transactionManager" /> <!-- <jpa:auditing auditor-aware-ref="auditorAware" /> --> <bean class="test.auditing.AuditingBeanDefinitionRegistryPostProcessor" /> </beans>
three bean(AnnotationBeanConfigurerAspect, AuditingEntityListener, AuditingBeanFactoryPostProcessor) declared in xml.
tests have failed. I do not know the reason why have failed. help me please.
Code:- testRepository-context.xml <?xml version="1.0" encoding="UTF-8"?> <beans xmlns="http://www.springframework.org/schema/beans" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:jpa="http://www.springframework.org/schema/data/jpa" xsi:schemaLocation="..."> <bean id="auditorAware" class="test.auditing.DefaultAuditorAware" /> <jpa:repositories base-package="test.auditing" entity-manager-factory-ref="entityManagerFactory" transaction-manager-ref="transactionManager" /> <!-- <jpa:auditing auditor-aware-ref="auditorAware" /> --> <!-- <bean class="test.auditing.AuditingBeanDefinitionRegistryPostProcessor" /> --> <bean class="org.springframework.beans.factory.aspectj.AnnotationBeanConfigurerAspect" factory-method="aspectOf" /> <bean class="org.springframework.data.jpa.domain.support.AuditingEntityListener" scope="prototype" abstract="true"> <property name="auditorAware"> <bean class="org.springframework.aop.framework.ProxyFactoryBean"> <property name="targetSource"> <bean class="org.springframework.aop.target.LazyInitTargetSource"> <property name="targetBeanName" ref="auditorAware" /> </bean> </property> </bean> </property> </bean> <bean class="org.springframework.data.jpa.domain.support.AuditingBeanFactoryPostProcessor"/> </beans>


Reply With Quote
