如何解决SpringBoot 加入AOP后无法注入的问题

SpringBoot 开启AOP后 出现无法注入的问题 真是坑的很啊~

提示错误

org.springframework.beans.factory.NoSuchBeanDefinitionException: No unique bean of type

或者

java.lang.ClassCastException: com.sun.proxy.$Proxy12 cannot be cast to cn.edu.nuc.SpringTest.service.impl.DemoServiceImpl

解决方案

在application.properties中添加配置

#true为使用CGLIB代理,false为JDK代理,默认为false
spring.aop.proxy-target-class=true

引以为戒啊!!!!!!!

springboot使用aop拦截controller干一些事导致service们@Autowired全部注入失败

springboot使用aop拦截controller干一些事导致controller里的service们@Autowired全部注入失败,报空指针

先集成使用aop吧

<dependency>
 <groupId>org.springframework.boot</groupId>
 <artifactId>spring-boot-starter-aop</artifactId>
</dependency>

properties修改

#aop
spring.aop.proxy-target-class=true
spring.aop.auto=true

proxy-target-class属性值决定是基于接口的还是基于类的代理被创建。如果proxy-target-class 属性值被设置为true,那么基于类的代理将起作用(这时需要cglib库)。

如果proxy-target-class属值被设置为false或者这个属性被省略,那么标准的JDK 基于接口的代理将起作用。

然后直接贴一个模型代码吧

import cc.datebook.utils.IpUtil;
import com.google.gson.Gson;
import org.aspectj.lang.ProceedingJoinPoint;
import org.aspectj.lang.annotation.*;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.context.annotation.Configuration;
import org.springframework.web.context.request.RequestAttributes;
import org.springframework.web.context.request.RequestContextHolder;
import org.springframework.web.context.request.ServletRequestAttributes;
import org.springframework.web.servlet.HandlerMapping;
import javax.servlet.http.HttpServletRequest;
import java.util.Map;
/**
 * Created by wangH on 2017/12/12.
 */
@Aspect
@Configuration
public class ControllerMonitorAop {
    private static final Logger logger = LoggerFactory.getLogger(ControllerMonitorAop.class);
    ThreadLocal<Long> startTime = new ThreadLocal<>();

    @Pointcut("execution(public * cc.datebook.web.*Controller.*(..))")
    public void excudeService() {}
    @Around("excudeService()")
    public Object doAround(ProceedingJoinPoint pjp) throws Throwable {
        RequestAttributes ra = RequestContextHolder.getRequestAttributes();
        ServletRequestAttributes sra = (ServletRequestAttributes) ra;
        HttpServletRequest request = sra.getRequest();
        String ipAddr = IpUtil.getIpAddr(request);
        String url = request.getRequestURL().toString();
        String method = request.getMethod();
        String uri = request.getRequestURI();
        String queryString = request.getQueryString();
        String params = "";
        if ("POST".equals(method)) {
            Object[] paramsArray = pjp.getArgs();
            params = argsArrayToString(paramsArray);
        } else {
            Map<?, ?> paramsMap = (Map<?, ?>) request.getAttribute(HandlerMapping.URI_TEMPLATE_VARIABLES_ATTRIBUTE);
            params = paramsMap.toString();
        }
        logger.info("request begin=>ipAddr: {}, url: {}, method: {}, uri: {}, params: {}", ipAddr, url, method, uri, params);
        // result的值就是被拦截方法的返回值
        Object result = pjp.proceed();
        Gson gson = new Gson();
        String ab = gson.toJson(result).toString();
        if (ab.length() > 200){
            ab = ab.substring(0,200);
        }
        logger.info("request end=>" + ab);
        return result;
    }
    /**
     * 请求参数拼装
     * @param paramsArray
     * @return
     */
    private String argsArrayToString(Object[] paramsArray) {
        String params = "";
        if (paramsArray != null && paramsArray.length > 0) {
            for (int i = 0; i < paramsArray.length; i++) {
                Gson gson = new Gson();
                Object jsonObj = gson.toJson(paramsArray[i]);
                params += jsonObj.toString() + " ";
            }
        }
        return params.trim();
    }
}

但是拦截所有controller之后发现 service都注入失败

解决方案

这个aop只能适用于 protect 和public

之后把controller中的所有方法都改成public

一个小坑吧~

以上为个人经验,希望能给大家一个参考,也希望大家多多支持我们。

(0)

相关推荐

  • Spring AOP使用@Aspect注解 面向切面实现日志横切的操作

    引言: AOP为Aspect Oriented Programming的缩写,意为:面向切面编程,通过预编译方式和运行期动态代理实现程序功能的统一维护的一种技术.AOP是OOP的延续,是软件开发中的一个热点,也是Spring框架中的一个重要内容,是函数式编程的一种衍生范型. 利用AOP可以对业务逻辑的各个部分进行隔离,从而使得业务逻辑各部分之间的耦合度降低,提高程序的可重用性,同时提高了开发的效率. 在Spring AOP中业务逻辑仅仅只关注业务本身,将日志记录,性能统计,安全控制,事务处理,异

  • 简单了解Spring IoC相关概念原理

    Spring Ioc是Spring框架的基础,本文会简单的介绍下Spring Ioc. Sprong Ioc即控制反转,它是一种通过描述(在java中可以是XML或注解)并通过第三方去产生或获取特定对象的方式. Spring IoC容器 1.Spring IoC容器的设计 Spring IoC容器的设计主要是基于BeanFactory和ApplicationContext这两个接口,其中ApplicationContext是BeanFactory的一个子接口.也就是说,BeanFactory是S

  • SpringAop日志找不到方法的处理

    SpringAop日志找不到方法 错误截图: 显示没有找到该方法,于是我找到对应的类和对应的方法: 这里我用了反射来获取方法名和参数: 错误打印的结果显示方法名获取没有错误,于是我查看参数的类型是否有错 结果一个都对不上- int类型反射得到的class: Integer反射得到的Class: -终于知道之前错误里的Ljavexxxx是哪里来的了- 由于model是一个接口 model反射的Class得到的是他的子类org.springframework.validation.support.B

  • Spring AOP基本概念

    目录 举个栗子给大家讲一下代理: 什么是AOP? 基本术语 (1)切面(Aspect) (2) 目标对象(Target) (3) 连接点(JoinPoint) (4) 切入点(PointCut) (5) 通知(Advice) (6) 织入(Weaving) 静态代理模式 动态代理模式 总结 举个栗子给大家讲一下代理: 我相信大家都知道明星吧. 大部分明星是都有经纪人的. 假如我们是一个大厂,现在想要找一个明星代理产品,那我们会直接找到明星吗?不.现实中,你大部分找到的都是找到明星的代理人(经纪人

  • SpringAOP切入点规范及获取方法参数的实现

    切入点规范 @Pointcut("execution(* com.example.server.service.TeacherService.*(..))") 上面的切入点会切入com.example.server.service.TeacherService下面的所有方法. 下面来详细介绍一下切入点表达式的规范. 1.execution():表达式主体. 2.第一个位置:表示返回类型, *号表示所有的类型. 3.第二个位置:表示需要拦截的包名.类名.方法名(方法参数). 需要注意的是

  • 如何解决SpringBoot 加入AOP后无法注入的问题

    SpringBoot 开启AOP后 出现无法注入的问题 真是坑的很啊~ 提示错误 org.springframework.beans.factory.NoSuchBeanDefinitionException: No unique bean of type 或者 java.lang.ClassCastException: com.sun.proxy.$Proxy12 cannot be cast to cn.edu.nuc.SpringTest.service.impl.DemoServiceI

  • 解决springboot的aop切面不起作用问题(失效的排查)

    检查下springboot的启动类是否开启扫描 @SpringBootApplication @ComponentScan(basePackages = {"com.zhangpu.springboot"}) 另外springboot默认开启的EnableAspectJAutoProxy为true 如果不放心可以增加: @EnableAspectJAutoProxy(proxyTargetClass=true) 第二种可能: 没有导入 相关的jar <dependency>

  • 解决Springboot项目启动后自动创建多表关联的数据库与表的方案

    熬夜写完,尚有不足,但仍在努力学习与总结中,而您的点赞与关注,是对我最大的鼓励! 在一些本地化项目开发当中,存在这样一种需求,即开发完成的项目,在第一次部署启动时,需能自行构建系统需要的数据库及其对应的数据库表. 若要解决这类需求,其实现在已有不少开源框架都能实现自动生成数据库表,如mybatis plus.spring JPA等,但您是否有想过,若要自行构建一套更为复杂的表结构时,这种开源框架是否也能满足呢,若满足不了话,又该如何才能实现呢? 我在前面写过一篇 Activiti工作流学习笔记(

  • 解决SpringBoot项目启动后网页显示Please sign in的问题

    Springboot启动项目后网页显示[Please sign in] 遇到的情况解决办法解决效果根本原因(依赖导错了)根本解决办法 遇到的情况 启动SpringBoot后,访问http://127.0.0.1:8080/t02/index,确莫名其妙的进入到了Please sign in页面. 解决办法 仔细看了下idea控制台的信息,发现出现了一个security password,原来是进入到了一个安全拦截界面,我们输入idea控制台打印的密码即可,username是user. 解决效果

  • 解决Springboot项目打包后的页面丢失问题(thymeleaf报错)

    目录 Springboot项目打包后的页面丢失 遇到的问题目前找到两种 Springboot打包ThymeLeaf报错 原因 解决办法 Springboot项目打包后的页面丢失 遇到的问题目前找到两种 返回视图路径以/开头,例如 /test/hello 在thymeleaf页面中,引入的页面以/开头,例如:<footer th:replace="/index::footer"></footer> 代码书写规范: @GetMapping("/about-

  • 解决SpringBoot 测试类无法自动注入@Autowired的问题

    原来的测试类的注解: @RunWith(SpringRunner.class) @SpringBootTest 一直没法自动注入,后来在@SpringBootTest, 加入启动类Application后就可以了 @RunWith(SpringRunner.class) @SpringBootTest(classes = Application.class) 补充:spring boot项目单元测试时,@Autowired无法注入Service解决方式 首先确认: 测试类所在包名要和启动类一致

  • 解决SpringBoot引用别的模块无法注入的问题

    目录 引用别的模块无法注入的问题 问题描述 解决方法 多模块项目中无法注入其他模块的springbean 引用别的模块无法注入的问题 前段时间尝试着利用空闲时间搭建了一个IIM消息通信系统,目前还是Demo级别,具体实现还在不断补充,在开发过程中遇到了一个小问题,在此分享出来,猛男请忽略. 问题描述 由于前期搭建的比较匆忙,搁那狂写调用逻辑,没注意自己的包名有点奇怪. 目前是分为这三个模块,客户端,公共处理模块,服务端,不过我正在琢磨着给这玩意再整个路由注册中心,便于客户端和服务端的横向拓展.

  • SpringBoot服务开启后通过端口访问无反应的解决

    SpringBoot入门Demo,一次深夜踩坑记录. springboot小项目开启后,访问端口无反应. 首先看我的项目目录: 项目的pom文件内容如下: <?xml version="1.0" encoding="UTF-8"?> <project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema

  • springboot 高版本后继续使用log4j的完美解决方法

    springboot  高版本后不支持log4j了,很多人还是喜欢log4j风格的日志,我们自己来加载log4j,其实很容易. 第一步:我们手动加入我们想要的log4j jar,在项目里面随便建一个文件夹,将用到的jar丢进去,右键 add to build path 第二步: 在main函数启动类所在的包或者其子包下写一个这样的类,用来加载log4j配置文件,是的,什么内容都没有. import org.springframework.boot.context.properties.Confi

  • 解决Springboot @Autowired 无法注入问题

    特别提醒:一定要注意文件结构 WebappApplication 一定要在包的最外层,否则Spring无法对所有的类进行托管,会造成@Autowired 无法注入. 1. 添加工具类获取在 Spring 中托管的 Bean (1)工具类 package com.common; import org.springframework.beans.BeansException; import org.springframework.beans.factory.NoSuchBeanDefinitionE

随机推荐