各位好,我在项目中尝试使用SpringAOP拦截子类调用父类的方法,发现AOP无法切入到父类中,困惑许久,在网上寻了各种方法都没有解决,希望各位同行可以帮我指出其中的问题,不胜感激。
子类:
@Repository("userLoginDao")
public class UserLoginDaoImpl extends BaseDao<UserLogin> implements IUserLoginDao{
@Override
public UserLogin addUserlogin(UserLogin userLogin) {
insertSelective(userLogin);
return userLogin;
}
}
** 父类: **
public class BaseDao<E> extends SqlSessionDaoSupport {
protected String daoName;
private SqlSessionTemplate sqlSessionTemplate = null;
@Autowired
protected void setSessionTemplate(SqlSessionTemplate sessionTemplate) {
super.setSqlSessionTemplate(sessionTemplate);
this.sqlSessionTemplate = sessionTemplate;
}
@SuppressWarnings("unchecked")
@PostConstruct
protected void init() {
ParameterizedType parameterizedType = (ParameterizedType) this.getClass().getGenericSuperclass();
Class<E> daoType = (Class<E>) parameterizedType.getActualTypeArguments()[0];
this.daoName = "mapper."+ daoType.getName().substring(daoType.getName().lastIndexOf(".") + 1) + "Mapper.";
}
@InsertLog(description="添加")
public int insertSelective(E bean) {
return this.getSqlSession().insert(this.daoName + "insertSelective", bean);
}
}
** AOP拦截器:**
@Aspect
@Order(90)
@Component
public class ServiceLogAspect {
private ThreadLocal<Map<String, Object>> serviceLocalMap = new ThreadLocal<Map<String, Object>>();
@Autowired
private SqlSessionFactory sqlSessionFactory;
//使用标签和匹配都试过不可以
// @Pointcut("@annotation(com.company.project.core.aoplog.InsertLog)")
@Pointcut("execution(* com.company.project.service.user.base.BaseDao.insert*(..))")
public void insertDaoAspect() {
}
// ----------------------------------对增加方法sql的记录
@Around("insertDaoAspect()")
public Object insertDaoAspect(final ProceedingJoinPoint pjp) throws Throwable {
Map<String, Object> map = serviceLocalMap.get();
// 获取操作的实体的类名
String modelName = null;
Field fields[] = pjp.getTarget().getClass().getDeclaredFields();// 获得对象所有属性
for (Field field : fields) {
field.setAccessible(true);
if ("daoName".equals(field.getName())) {
modelName = field.get(pjp.getTarget()).toString();
}
}
// 获取将要执行的sql语句所在Mapper
String daoName = "mapper." + modelName + "Mapper.";
Object obj = (pjp.getArgs().length > 0 ? pjp.getArgs()[0] : null);// 注意空指针异常
// 获取执行的修改sql语句
String sql = sqlSessionFactory.getConfiguration().getMappedStatement(daoName + pjp.getSignature().getName())
.getBoundSql(obj).getSql();
// 获取存储sql语句的列表
List<Map<String, Object>> listMap = (List<Map<String, Object>>) map.get("daoOperation");
if (listMap == null) {
listMap = new ArrayList<Map<String, Object>>();
map.put("daoOperation", listMap);
}
Map<String, Object> daoMap = new HashMap<String, Object>();
listMap.add(daoMap);
daoMap.put("daoMethodName", pjp.getTarget().getClass().getName() + "." + pjp.getSignature().getName());
daoMap.put("daoParameter", obj);
daoMap.put("daoType", "添加");
daoMap.put("daoSql", sql.replaceAll("\n", ""));
daoMap.put("start", System.currentTimeMillis());
Object value = pjp.proceed();
daoMap.put("return", value);
daoMap.put("runTime", System.currentTimeMillis() - ((Long) daoMap.get("start")));
// 向卡夫卡发送日志信息
log.debug("-----------------//" + JSONObject.toJSONString(daoMap));
return value;
// }else {
// Object value = pjp.proceed();
// return value;
// }
}
}
** 自定义注解:**
@Target({ElementType.PARAMETER,ElementType.METHOD}) //ElementType.PARAMETER 方法参数,ElementType.METHOD 方法(表示这个注解是方法的注解)
@Retention(RetentionPolicy.RUNTIME) //注解会在class字节码文件中存在,在运行时可以通过反射获取到
@Documented//说明该注解将被包含在javadoc中
public @interface InsertLog {
String description() default "";
String versions() default "";
}
** 主要配置 spring-base : **
<context:annotation-config />
<!-- 配置要扫描的包 -->
<context:component-scan base-package="com.company.project" />
<!-- proxy-target-class默认"false",更改为"ture"使用CGLib动态代理 -->
<aop:aspectj-autoproxy proxy-target-class="true" />
<!-- 引入配置文件 -->
<bean id="propertyConfigurer" class="org.springframework.beans.factory.config.PropertyPlaceholderConfigurer">
<property name="locations">
<list>
<value>classpath:db.properties</value>
<value>classpath:redis.properties</value>
</list>
</property>
</bean>
<import resource="classpath:spring/spring-dubbo-provider.xml" />
<import resource="classpath:spring/spring-mybatis.xml" />
<!-- <import resource="classpath:spring/spring-redis.xml" /> -->