内容回顾 | spring零配置AOP踩坑指南

云中志

共 4961字,需浏览 10分钟

 ·

2021-09-22 02:48

今天也不打算更新技术内容了,我们回顾下spring boot关于切面编程的相关内容。
今天早上和家里一大家子人一起吃饭,然后下午打了一下午的麻将,没想到娱乐也能这么累,而且由于早上吃的有点多,所以晚上都不想吃饭了
前言
作为一名合格的爱码仕,对于AOP就算你没有一见,至少百闻了,那么什么是AOP呢,通俗来讲就是面向切面编程,是对面向对象编程的一种拓展,用于解决一些面向对象编程无法解决的问题。
Baidu百科解释是:
在软件业,AOP为Aspect Oriented Programming的缩写,意为:在软件业,AOP为Aspect Oriented Programming的缩写,意为:面向切面编程,通过预编译方式和运行期动态代理实现程序功能的统一维护的一种技术。AOP是OOP的延续,是软件开发中的一个热点,也是Spring框架中的一个重要内容,是函数式编程的一种衍生范型。利用AOP可以对业务逻辑的各个部分进行隔离,从而使得业务逻辑各部分之间的耦合度降低,提高程序的可重用性,同时提高了开发的效率。
这里关于AOP的相关知识点,不做过多的解释说明,一方面我自认为自己积累的还不够,一方面,做事我喜欢实践出真知,一个字,就是干……
好了,废话不多说,直接开始吧。
今天照着书,试着配了AOP(全注解),结果踩了各种坑,后来参考书附带的源码,终于走出来了,现在总结一下
  • 除了spring的jar包以外,还需要导入以下包:

1、Spring核心配置文件beans.xml(这里是大坑)

<?xml version="1.0" encoding="UTF-8"?><beans xmlns="http://www.springframework.org/schema/beans"    xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"    xmlns:context="http://www.springframework.org/schema/context"    xmlns:aop="http://www.springframework.org/schema/aop"    xsi:schemaLocation="http://www.springframework.org/schema/beans     http://www.springframework.org/schema/beans/spring-beans-4.0.xsd    http://www.springframework.org/schema/context    http://www.springframework.org/schema/context/spring-context-4.0.xsd    http://www.springframework.org/schema/aop    http://www.springframework.org/schema/aop/spring-aop-4.0.xsd">    <!-- 启动@AspectJ支持 -->    <!-- <bean        class="org.springframework.aop.aspectj.annotation.AnnotationAwareAspectJAutoProxyCreator" /> -->    <context:component-scan        base-package="com.sysker.bean,com.sysker.aspect">        <context:include-filter type="annotation"            expression="org.aspectj.lang.annotation.Aspect" />    </context:component-scan><!-- 设置AOP为自动代理 -->    <aop:aspectj-autoproxy />    </beans>


  • 如果全部采用注解的话,bean是不需要在这里配置的,只需要在对应的类上面写上@Component("name")注解即可,前面不清楚,所以我在这个坑里呆了很久,书上也没说,自己也没去查

  • 这里的另外一个坑就是这里:

<context:component-scan        base-package="com.sysker.bean,com.sysker.aspect">        <context:include-filter type="annotation"            expression="org.aspectj.lang.annotation.Aspect" />    </context:component-scan>

  • 如果这里路径配置有问题的话,会提示找不到bean,错误信息大概如下:

Loading XML bean definitions from class path resource [beans.xml]Exception in thread "main" org.springframework.beans.factory.NoSuchBeanDefinitionException: No bean named 'hello' available    at org.springframework.beans.factory.support.DefaultListableBeanFactory.getBeanDefinition(DefaultListableBeanFactory.java:686)    at org.springframework.beans.factory.support.AbstractBeanFactory.getMergedLocalBeanDefinition(AbstractBeanFactory.java:1210)    at org.springframework.beans.factory.support.AbstractBeanFactory.doGetBean(AbstractBeanFactory.java:291)    at org.springframework.beans.factory.support.AbstractBeanFactory.getBean(AbstractBeanFactory.java:204)    at org.springframework.context.support.AbstractApplicationContext.getBean(AbstractApplicationContext.java:1095)    at com.sysker.test.AspectJTest.main(AspectJTest.java:22)

  • base-package里面可以配置多个路径,一定要完整

2、 Aspect类(这里有另外的大坑)

package com.sysker.aspect;import org.aspectj.lang.annotation.Aspect;import org.aspectj.lang.annotation.Before;@Aspectpublic class AuthAspect {    @Before("execution(* com.sysker.impl.*.*(..))")    public void authority() {        System.out.println("模拟执行权限检查");    }}


这里就有另外一个大坑在等着你,主要会出错的地方还是路径的问题:

@Before("execution(* com.sysker.impl.*.*(..))")
  • 路径必须正确,否则是没有效果了,比如我的路径,impl下的实现类要实现AOP,那么我的路径是要配到impl,然后还要有.. ,不然就是各种无效果,而且还不报错;
  • 还要提一下,Aspect必须要注解,注解,注解,就这样的@Aspect,然后后面的@Before("execution(* com.sysker.impl..(..))"),就是要执行的操作
  • 如果要针对某一个类,比如HelloImpl类,这需要写出具体的类:
@Before("execution(* com.sysker.impl.HelloImpl.*(..))")
  • 如果要针对某一个的具体方法,就需要写出具体的类的方法:

@Before("execution(* com.sysker.impl.HelloImpl.foo(..))")

3、service及Impl

package com.sysker.bean;public interface Hello {    void foo();    int addUser(String name, String pass);}package com.sysker.bean;public interface World {    public void bar();    }
  • service是不要注解的,也没必要

package com.sysker.impl;import org.springframework.stereotype.Component;import com.sysker.bean.Hello;@Component("hello")public class HelloImpl implements Hello {    @Override    public void foo() {        System.out.println("执行Hello组件的foo()方法");    }    @Override    public int addUser(String name, String pass) {        System.out.println("执行Hello组件的addUser添加用户:" + name);        return 20;    }}package com.sysker.impl;import org.springframework.stereotype.Component;import com.sysker.bean.World;@Component("world")public class WorldImpl implements World {    @Override    public void bar() {        System.out.println("执行World组件的bar()方法");    }    }


  • 这里需要注意的就是上面提到的,要注解@Component("world"),后面通过Spring容器创建对象要用到

    4、测试类

正常运行结果:

总结

今天虽然在这个问题上快纠结了一天,但总算功夫没白费,终于把这个坑填平了,收获满满,继续加油,不说了,我要继续去写bug了!!!

推荐阅读


1. 手动创建spring boot项目
2. 啥?你还不会创建spring项目!!!
3学习资源分享
4. java后端学习流程








Copyright ©2021 云中志




浏览 25
点赞
评论
收藏
分享

手机扫一扫分享

分享
举报
评论
图片
表情
推荐
点赞
评论
收藏
分享

手机扫一扫分享

分享
举报