Skip to content

Commit dd8b7b0

Browse files
author
JARVIS SONG
committed
auditing
1 parent 514e1a2 commit dd8b7b0

13 files changed

+366
-64
lines changed
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,38 @@
1+
/*
2+
* Copyright 2012-2019 the original author or authors.
3+
*
4+
* Licensed under the Apache License, Version 2.0 (the "License");
5+
* you may not use this file except in compliance with the License.
6+
* You may obtain a copy of the License at
7+
*
8+
* https://www.apache.org/licenses/LICENSE-2.0
9+
*
10+
* Unless required by applicable law or agreed to in writing, software
11+
* distributed under the License is distributed on an "AS IS" BASIS,
12+
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13+
* See the License for the specific language governing permissions and
14+
* limitations under the License.
15+
*/
16+
package org.springframework.data.mybatis.domain.support;
17+
18+
import org.springframework.beans.factory.ObjectFactory;
19+
import org.springframework.beans.factory.annotation.Configurable;
20+
import org.springframework.util.Assert;
21+
22+
/**
23+
* .
24+
*
25+
* @author JARVIS SONG
26+
*/
27+
@Configurable
28+
public class AuditingEntityListener {
29+
30+
public void setAuditingHandler(ObjectFactory<MybatisAuditingHandler> auditingHandler) {
31+
Assert.notNull(auditingHandler, "AuditingHandler must not be null!");
32+
MybatisAuditingHandler handler = auditingHandler.getObject();
33+
if (null != handler.getSqlSessionTemplate()) {
34+
handler.getSqlSessionTemplate().getConfiguration().addInterceptor(new AuditingInterceptor(auditingHandler));
35+
}
36+
}
37+
38+
}
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,81 @@
1+
/*
2+
* Copyright 2012-2019 the original author or authors.
3+
*
4+
* Licensed under the Apache License, Version 2.0 (the "License");
5+
* you may not use this file except in compliance with the License.
6+
* You may obtain a copy of the License at
7+
*
8+
* https://www.apache.org/licenses/LICENSE-2.0
9+
*
10+
* Unless required by applicable law or agreed to in writing, software
11+
* distributed under the License is distributed on an "AS IS" BASIS,
12+
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13+
* See the License for the specific language governing permissions and
14+
* limitations under the License.
15+
*/
16+
package org.springframework.data.mybatis.domain.support;
17+
18+
import java.util.Map;
19+
20+
import javax.persistence.Entity;
21+
22+
import org.apache.ibatis.executor.Executor;
23+
import org.apache.ibatis.mapping.MappedStatement;
24+
import org.apache.ibatis.mapping.SqlCommandType;
25+
import org.apache.ibatis.plugin.Interceptor;
26+
import org.apache.ibatis.plugin.Intercepts;
27+
import org.apache.ibatis.plugin.Invocation;
28+
import org.apache.ibatis.plugin.Signature;
29+
30+
import org.springframework.beans.factory.ObjectFactory;
31+
import org.springframework.data.mybatis.repository.support.ResidentParameterName;
32+
33+
/**
34+
* .
35+
*
36+
* @author JARVIS SONG
37+
*/
38+
@Intercepts({ @Signature(type = Executor.class, method = "update", args = { MappedStatement.class, Object.class }), })
39+
public class AuditingInterceptor implements Interceptor {
40+
41+
private MybatisAuditingHandler handler;
42+
43+
public AuditingInterceptor(ObjectFactory<MybatisAuditingHandler> auditingHandler) {
44+
45+
if (null != auditingHandler) {
46+
this.handler = auditingHandler.getObject();
47+
}
48+
}
49+
50+
@Override
51+
public Object intercept(Invocation invocation) throws Throwable {
52+
if (null == this.handler) {
53+
return invocation.proceed();
54+
}
55+
56+
MappedStatement mappedStatement = (MappedStatement) invocation.getArgs()[0];
57+
SqlCommandType sqlCommandType = mappedStatement.getSqlCommandType();
58+
Object parameter = invocation.getArgs()[1];
59+
Object entity;
60+
if (parameter instanceof Map) {
61+
entity = ((Map) parameter).get(ResidentParameterName.ENTITY);
62+
}
63+
else {
64+
entity = parameter;
65+
}
66+
67+
if (null == entity || !entity.getClass().isAnnotationPresent(Entity.class)) {
68+
return invocation.proceed();
69+
}
70+
71+
if (sqlCommandType == SqlCommandType.INSERT) {
72+
this.handler.markCreated(entity);
73+
}
74+
else if (sqlCommandType == SqlCommandType.UPDATE) {
75+
this.handler.markModified(entity);
76+
}
77+
78+
return invocation.proceed();
79+
}
80+
81+
}
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,51 @@
1+
/*
2+
* Copyright 2012-2019 the original author or authors.
3+
*
4+
* Licensed under the Apache License, Version 2.0 (the "License");
5+
* you may not use this file except in compliance with the License.
6+
* You may obtain a copy of the License at
7+
*
8+
* https://www.apache.org/licenses/LICENSE-2.0
9+
*
10+
* Unless required by applicable law or agreed to in writing, software
11+
* distributed under the License is distributed on an "AS IS" BASIS,
12+
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13+
* See the License for the specific language governing permissions and
14+
* limitations under the License.
15+
*/
16+
package org.springframework.data.mybatis.domain.support;
17+
18+
import org.mybatis.spring.SqlSessionTemplate;
19+
20+
import org.springframework.data.auditing.AuditingHandler;
21+
import org.springframework.data.mapping.PersistentEntity;
22+
import org.springframework.data.mapping.PersistentProperty;
23+
import org.springframework.data.mapping.context.MappingContext;
24+
import org.springframework.data.mapping.context.PersistentEntities;
25+
26+
/**
27+
* .
28+
*
29+
* @author JARVIS SONG
30+
*/
31+
public class MybatisAuditingHandler extends AuditingHandler {
32+
33+
private SqlSessionTemplate sqlSessionTemplate;
34+
35+
public MybatisAuditingHandler(
36+
MappingContext<? extends PersistentEntity<?, ?>, ? extends PersistentProperty<?>> mappingContext) {
37+
super(mappingContext);
38+
}
39+
40+
public MybatisAuditingHandler(PersistentEntities entities) {
41+
super(entities);
42+
}
43+
44+
public void setSqlSessionTemplate(SqlSessionTemplate sqlSessionTemplate) {
45+
this.sqlSessionTemplate = sqlSessionTemplate;
46+
}
47+
48+
public SqlSessionTemplate getSqlSessionTemplate() {
49+
return sqlSessionTemplate;
50+
}
51+
}

spring-data-mybatis/src/main/java/org/springframework/data/mybatis/repository/config/EnableMybatisAuditing.java

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -68,4 +68,6 @@
6868
*/
6969
String dateTimeProviderRef() default "";
7070

71+
String sqlSessionTemplateRef() default "";
72+
7173
}
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,83 @@
1+
/*
2+
* Copyright 2012-2019 the original author or authors.
3+
*
4+
* Licensed under the Apache License, Version 2.0 (the "License");
5+
* you may not use this file except in compliance with the License.
6+
* You may obtain a copy of the License at
7+
*
8+
* https://www.apache.org/licenses/LICENSE-2.0
9+
*
10+
* Unless required by applicable law or agreed to in writing, software
11+
* distributed under the License is distributed on an "AS IS" BASIS,
12+
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13+
* See the License for the specific language governing permissions and
14+
* limitations under the License.
15+
*/
16+
package org.springframework.data.mybatis.repository.config;
17+
18+
import java.lang.annotation.Annotation;
19+
import java.util.Map;
20+
21+
import org.springframework.core.annotation.AnnotationAttributes;
22+
import org.springframework.core.type.AnnotationMetadata;
23+
import org.springframework.data.auditing.config.AnnotationAuditingConfiguration;
24+
import org.springframework.util.Assert;
25+
26+
/**
27+
* .
28+
*
29+
* @author JARVIS SONG
30+
* @since 2.0.1
31+
*/
32+
public class MybatisAnnotationAuditingConfiguration implements MybatisAuditingConfiguration {
33+
34+
private static final String MISSING_ANNOTATION_ATTRIBUTES = "Couldn't find annotation attributes for %s in %s!";
35+
36+
private final AnnotationAttributes attributes;
37+
38+
/**
39+
* Creates a new instance of {@link AnnotationAuditingConfiguration} for the given
40+
* {@link AnnotationMetadata} and annotation type.
41+
* @param metadata must not be {@literal null}.
42+
* @param annotation must not be {@literal null}.
43+
*/
44+
public MybatisAnnotationAuditingConfiguration(AnnotationMetadata metadata, Class<? extends Annotation> annotation) {
45+
46+
Assert.notNull(metadata, "AnnotationMetadata must not be null!");
47+
Assert.notNull(annotation, "Annotation must not be null!");
48+
49+
Map<String, Object> attributesSource = metadata.getAnnotationAttributes(annotation.getName());
50+
51+
if (attributesSource == null) {
52+
throw new IllegalArgumentException(String.format(MISSING_ANNOTATION_ATTRIBUTES, annotation, metadata));
53+
}
54+
55+
this.attributes = new AnnotationAttributes(attributesSource);
56+
}
57+
58+
@Override
59+
public String getAuditorAwareRef() {
60+
return this.attributes.getString("auditorAwareRef");
61+
}
62+
63+
@Override
64+
public boolean isSetDates() {
65+
return this.attributes.getBoolean("setDates");
66+
}
67+
68+
@Override
69+
public String getDateTimeProviderRef() {
70+
return this.attributes.getString("dateTimeProviderRef");
71+
}
72+
73+
@Override
74+
public boolean isModifyOnCreate() {
75+
return this.attributes.getBoolean("modifyOnCreate");
76+
}
77+
78+
@Override
79+
public String getSqlSessionTemplateRef() {
80+
return this.attributes.getString("sqlSessionTemplateRef");
81+
}
82+
83+
}
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,29 @@
1+
/*
2+
* Copyright 2012-2019 the original author or authors.
3+
*
4+
* Licensed under the Apache License, Version 2.0 (the "License");
5+
* you may not use this file except in compliance with the License.
6+
* You may obtain a copy of the License at
7+
*
8+
* https://www.apache.org/licenses/LICENSE-2.0
9+
*
10+
* Unless required by applicable law or agreed to in writing, software
11+
* distributed under the License is distributed on an "AS IS" BASIS,
12+
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13+
* See the License for the specific language governing permissions and
14+
* limitations under the License.
15+
*/
16+
package org.springframework.data.mybatis.repository.config;
17+
18+
import org.springframework.data.auditing.config.AuditingConfiguration;
19+
20+
/**
21+
* .
22+
*
23+
* @author JARVIS SONG
24+
*/
25+
public interface MybatisAuditingConfiguration extends AuditingConfiguration {
26+
27+
String getSqlSessionTemplateRef();
28+
29+
}

spring-data-mybatis/src/main/java/org/springframework/data/mybatis/repository/config/MybatisAuditingRegistrar.java

Lines changed: 40 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -20,11 +20,16 @@
2020
import org.springframework.beans.factory.config.BeanDefinition;
2121
import org.springframework.beans.factory.support.BeanDefinitionBuilder;
2222
import org.springframework.beans.factory.support.BeanDefinitionRegistry;
23+
import org.springframework.beans.factory.support.RootBeanDefinition;
2324
import org.springframework.context.annotation.ImportBeanDefinitionRegistrar;
2425
import org.springframework.core.type.AnnotationMetadata;
2526
import org.springframework.data.auditing.config.AuditingBeanDefinitionRegistrarSupport;
2627
import org.springframework.data.auditing.config.AuditingConfiguration;
28+
import org.springframework.data.config.ParsingUtils;
29+
import org.springframework.data.mybatis.domain.support.AuditingEntityListener;
30+
import org.springframework.data.mybatis.domain.support.MybatisAuditingHandler;
2731
import org.springframework.util.Assert;
32+
import org.springframework.util.StringUtils;
2833

2934
/**
3035
* {@link ImportBeanDefinitionRegistrar} to enable {@link EnableMybatisAuditing}
@@ -40,10 +45,24 @@ protected Class<? extends Annotation> getAnnotation() {
4045
return EnableMybatisAuditing.class;
4146
}
4247

48+
@Override
49+
protected MybatisAuditingConfiguration getConfiguration(AnnotationMetadata annotationMetadata) {
50+
return new MybatisAnnotationAuditingConfiguration(annotationMetadata, this.getAnnotation());
51+
}
52+
4353
@Override
4454
protected void registerAuditListenerBeanDefinition(BeanDefinition auditingHandlerDefinition,
4555
BeanDefinitionRegistry registry) {
56+
if (!registry.containsBeanDefinition(BeanDefinitionNames.MYBATIS_MAPPING_CONTEXT_BEAN_NAME)) {
57+
registry.registerBeanDefinition(BeanDefinitionNames.MYBATIS_MAPPING_CONTEXT_BEAN_NAME, //
58+
new RootBeanDefinition(MybatisMappingContextFactoryBean.class));
59+
}
4660

61+
BeanDefinitionBuilder builder = BeanDefinitionBuilder.rootBeanDefinition(AuditingEntityListener.class);
62+
builder.addPropertyValue("auditingHandler",
63+
ParsingUtils.getObjectFactoryBeanDefinition(this.getAuditingHandlerBeanName(), null));
64+
this.registerInfrastructureBeanWithId(builder.getRawBeanDefinition(), AuditingEntityListener.class.getName(),
65+
registry);
4766
}
4867

4968
@Override
@@ -61,8 +80,28 @@ protected String getAuditingHandlerBeanName() {
6180

6281
@Override
6382
protected BeanDefinitionBuilder getAuditHandlerBeanDefinitionBuilder(AuditingConfiguration configuration) {
64-
BeanDefinitionBuilder builder = super.getAuditHandlerBeanDefinitionBuilder(configuration);
83+
Assert.notNull(configuration, "AuditingConfiguration must not be null!");
84+
85+
BeanDefinitionBuilder builder = this.configureDefaultAuditHandlerAttributes(configuration,
86+
BeanDefinitionBuilder.rootBeanDefinition(MybatisAuditingHandler.class));
6587
return builder.addConstructorArgReference(BeanDefinitionNames.MYBATIS_MAPPING_CONTEXT_BEAN_NAME);
6688
}
6789

90+
@Override
91+
protected BeanDefinitionBuilder configureDefaultAuditHandlerAttributes(AuditingConfiguration configuration,
92+
BeanDefinitionBuilder builder) {
93+
BeanDefinitionBuilder beanDefinitionBuilder = super.configureDefaultAuditHandlerAttributes(configuration,
94+
builder);
95+
96+
MybatisAuditingConfiguration mac = (MybatisAuditingConfiguration) configuration;
97+
if (StringUtils.hasText(mac.getSqlSessionTemplateRef())) {
98+
builder.addPropertyReference("sqlSessionTemplate", mac.getSqlSessionTemplateRef());
99+
}
100+
else {
101+
builder.addPropertyReference("sqlSessionTemplate", "sqlSessionTemplate");
102+
}
103+
104+
return beanDefinitionBuilder;
105+
}
106+
68107
}

0 commit comments

Comments
 (0)