当前位置: 首页 > 知识库问答 >
问题:

控制器中的spring AOP切入点

司马自明
2023-03-14

我定义了这个类方面,它对服务很好(除非用户有角色管理器,否则不允许访问,但对控制器(?)没有限制

@Aspect
public class DeviceAspect extends ServiceSupport {


    @Pointcut("execution(* fo.belecam.services.client.ManageLicenseService.*(..))")
    public void manage() {
    }

    @Pointcut("execution(* fo.belecam.services.client.AwardService.*(..))")
    public void award() {
    }

    @Pointcut("execution(* fo.belecam.services.client.DeviceService.*(..))")
    public void handleDeviceServiceMethod() {
    }

    @Pointcut("execution(* fo.belecam.controller.manage.ImportController.*(..))")
    public void handleImportController() {
    }


    @Before("fo.belecam.services.aop.DeviceAspect.handleImportController() || fo.belecam.services.aop.DeviceAspect.handleDeviceServiceMethod() || fo.belecam.services.aop.DeviceAspect.manage() || fo.belecam.services.aop.DeviceAspect.award()")
    @After ("fo.belecam.services.aop.DeviceAspect.handleImportController() || fo.belecam.services.aop.DeviceAspect.handleDeviceServiceMethod() || fo.belecam.services.aop.DeviceAspect.manage() || fo.belecam.services.aop.DeviceAspect.award()")
    public void before(JoinPoint _jp) {
        User user = getUser();
        if(user == null || user.getUserRole() != UserRole.MANAGER) {
            throw new NoSufficientRoleException(user == null ? null : user.getUserRole(), UserRole.MANAGER);
        }
    }

}

和ImportController:

@SuppressWarnings("deprecation")
public class ImportController extends AbstractFormController {


    private String view;

    private String successView;

    @Autowired
    protected UserService userService;

    @Autowired
    private ManageDeviceService manageDeviceService;

    public String getView() {
        return view;
    }

    public void setView(String view) {
        this.view = view;
    }

    public String getSuccessView() {
        return successView;
    }

    public void setSuccessView(String successView) {
        this.successView = successView;
    }


    @Override
    public ModelAndView processFormSubmission(final HttpServletRequest request,
            HttpServletResponse response, Object command, BindException errors)
            throws Exception {

        final ModelAndView mav = new ModelAndView(getView());

        FileUploadCommand file = (FileUploadCommand)command;

        MultipartFile multipartFile = file.getFile();

        if(multipartFile!=null && multipartFile.getSize()>0) {
            Workbook workbook = Workbook.getWorkbook(multipartFile.getInputStream());
            DataCollector dataCollector = new XLSDataCollector(workbook, true);
            final List<Application> applications = manageDeviceService.loadApplications (dataCollector.getDataCollection());
            List<ApplicationImporterError> importationErrors = manageDeviceService.validateApplications(applications);
            savedApplications.add(manageDeviceService.getApplicationById(application.getId(), true));


        }
        return mav;
    }

    @Override
    public ModelAndView showForm(HttpServletRequest request, HttpServletResponse arg1, BindException errors)
            throws Exception {

        return new ModelAndView(getView());
    }



    }

    /**
     * @param applications
     * @param competentBody
     * @return
     * @throws Exception
     */
    private List<Application> saveApplications(List<Application> applications,User user) throws Exception {

        return manageDeviceService.saveImportedApplications (applications, user);
    }

    /**
     * @param session
     * @return
     */
    public User getUser(HttpSession session) {

        User user = (User) session.getAttribute(Const.SESSION_USER);
        if (user == null) {
            user = new User();
        }
        return user;
    }
}

当我作为userrole.manager登录时,将调用before(joinpointjp)方法,否则不是

我明白了,当我只是在浏览器中粘贴URL时,前面的方法(joinpointjp)没有被调用....http://127.0.0.1:7001/devices/manage/import.do

共有2个答案

江文斌
2023-03-14

spring基于动态代理的AOP的一个限制是它只能从文档中建议公共连接点:

http://docs.spring.io/spring/docs/current/spring-framework-reference/html/aop.html

由于spring的AOP框架的基于代理的性质,受保护的方法根据定义是不被截取的,对于JDK代理(如果这不适用)和CGLIB代理(如果这在技术上是可能的,但对于AOP目的不推荐)都是不被截取的。因此,任何给定的切入点都将只与公共方法匹配!如果您的拦截需求包括受保护/私有方法甚至构造函数,那么考虑使用spring驱动的原生AspectJ编织,而不是spring的基于代理的AOP框架。这构成了具有不同特性的AOP使用的不同模式,所以在做出决定之前一定要先让自己熟悉编织。

您的许多控制器方法都是protected的,所以尽管您的控制器注册为spring bean(大概是)--将不建议使用非公共方法。

魏元白
2023-03-14

我遇到了同样的问题,对于存储库的建议是有效的,而对于控制器的建议却不行。最后我找到了解决办法。简而言之,您需要确保您的AOP定义加载在Servlet上下文中,而不是一个不同的上下文中。

在我的例子中,我的spring AOP定义是在tools-config.xml中定义的。从这里搬过来之后

<context-param>
    <param-name>contextConfigLocation</param-name>
    <param-value>classpath:spring/tools-config.xml</param-value>
</context-param>

<listener>
    <listener-class>org.springframework.web.context.ContextLoaderListener</listener-class>
</listener>

到这里,

<servlet>
    <servlet-name>petclinic</servlet-name>
    <servlet-class>org.springframework.web.servlet.DispatcherServlet</servlet-class>
    <init-param>
        <param-name>contextConfigLocation</param-name>
        <param-value>classpath:spring/mvc-core-config.xml, classpath:spring/tools-config.xml</param-value>
    </init-param>
    <load-on-startup>1</load-on-startup>
</servlet>

对控制器的建议正在起作用。

 类似资料:
  • 我想在Spring(3.2.3)@Controller中的每个方法之前运行一些代码。我定义了以下内容,但它不会运行。我怀疑切入点表达式不正确。 dispatcher-servlet.xml C. E. W. C. ThingAspect

  • 问题内容: 我是Angular的新手,正在尝试弄清楚该怎么做… 使用AngularJS,如何注入要在另一个控制器中使用的控制器? 我有以下片段: 执行此操作时,出现错误: 我是否应该尝试在另一个控制器内部使用一个控制器,还是应该将此服务用作服务? 问题答案: 如果您打算掌握已经实例化的另一个组件的控制器,并且如果您遵循的是基于组件/指令的方法,则始终可以遵循某个层次结构的另一个组件中的控制器(一个

  • 我在我的本地集群中安装入口控制器时遇到了一些问题(使用Kubes祈祷创建,运行MetalLB创建LoadBalancer。)。 我尝试使用nginx、traefik和kong,但都得到了相同的结果。 我正在使用以下值安装nginx helm图表。yaml: 使用命令: 当我在集群中部署入口控制器时,会创建一个服务(例如nginx的nginx-ingress-控制器)。此服务属于LoadBalanc

  • 所以我有一个Laravel控制器: 目前,我正在使用artisan(在引擎盖下运行PHP的内置开发Web服务器)运行应用程序: 我想将控制台消息记录到artisan进程的管道中。

  • 准入控制器(Admission Controller)位于 API Server 中,在对象被持久化之前,准入控制器拦截对 API Server 的请求,一般用来做身份验证和授权。其中包含两个特殊的控制器:MutatingAdmissionWebhook 和 ValidatingAdmissionWebhook。分别作为配置的变异和验证准入控制 webhook。 变更(Mutating)准入控制: