Gangmax Blog

Spring AOP

This is an example how to use Spring AOP.

Here is the original code before using Spring AOP.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
/*
* BaseDynamicDataSourceHandlerImpl.java: This class is the base class for
* all the handler classes which need the dynamic DataSource support. In each
* subclass handling method, it should invoke the "setDataSourceContext(...)"
* method to switch the DataSource(by passing the "mallId" argument from
* the handling method's arguments).
*/
public abstract class BaseDynamicDataSourceHandlerImpl {
...

/**
* Set the DataSource context according to the current mall.
*
* @param mallId
*/
public void setDataSourceContext(Integer mallId) {
...
}

...
}



/*
* CustomerFlowHandlerImpl.java: A subclass of "BaseDynamicDataSourceHandlerImpl"
* class.
*/
@Component
public class CustomerFlowHandlerImpl extends BaseDynamicDataSourceHandlerImpl implements CustomerFlowHandler {
...

@Override
public DataResult<String, Integer> getCustomerFlowTrendHistory(Integer mallId, CustomerType customerType,
Integer floorId, Integer historyDayCount) {
setDataSourceContext(mallId);
...
}

@Override
public DataResult<String, Integer> getCustomerFlowTrendAverage(Integer mallId, CustomerType customerType,
Integer floorId, Integer historyDayCount) {
setDataSourceContext(mallId);
...
}

@Override
public DataResult<String, Integer> getEnterShopCustomerAmountHistory(Integer mallId, CustomerType customerType,
Integer floorId, Integer historyDayCount) {
setDataSourceContext(mallId);
...
}

@Override
public DataResult<String, Integer> getEnterShopCustomerAmountAverage(Integer mallId, CustomerType customerType,
Integer floorId, Integer historyDayCount) {
setDataSourceContext(mallId);
...
}

...
}

According to the “DRY” principle, this should be improved. The following solution is done with Spring AOP. The solution comes from here and here.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
/*
* DynamicDataSourceAspect.java: The Aspect implementation which defines the pointcut
* for each public method in any subclass of "BaseDynamicDataSourceHandlerImpl", and
* makes the invocation of the "setDataSourceContext"method.
*/
@Component
@Aspect
public class DynamicDataSourceAspect {
@Before("execution(public * com.jcloud.zhike.handler.impl.BaseDynamicDataSourceHandlerImpl+.*(..)) && args(mallId,..)")
public void setDynamicDataSource(JoinPoint joinPoint, Integer mallId) {
BaseDynamicDataSourceHandlerImpl target = (BaseDynamicDataSourceHandlerImpl)joinPoint.getTarget();
target.setDataSourceContext(mallId);
}
}



/*
* CustomerFlowHandlerImpl.java: Now the "setDataSourceContext(...)" invocation lines can be removed.
*/
@Component
public class CustomerFlowHandlerImpl extends BaseDynamicDataSourceHandlerImpl implements CustomerFlowHandler {
...

@Override
public DataResult<String, Integer> getCustomerFlowTrendHistory(Integer mallId, CustomerType customerType,
Integer floorId, Integer historyDayCount) {
...
}

@Override
public DataResult<String, Integer> getCustomerFlowTrendAverage(Integer mallId, CustomerType customerType,
Integer floorId, Integer historyDayCount) {
...
}

@Override
public DataResult<String, Integer> getEnterShopCustomerAmountHistory(Integer mallId, CustomerType customerType,
Integer floorId, Integer historyDayCount) {
...
}

@Override
public DataResult<String, Integer> getEnterShopCustomerAmountAverage(Integer mallId, CustomerType customerType,
Integer floorId, Integer historyDayCount) {
...
}

...
}

More basic concepts about Spring AOP can be found in the offical document here.

Comments