zoukankan      html  css  js  c++  java
  • Spring注解配置Aop

    之前学习了SpringAop的基本原理。http://www.cnblogs.com/expiator/p/7977975.html

    现在尝试使用注解来配置SpringAop。

    Aop,面向切面编程。包括切入点(PointCut)、切面(Aspect),连接点(Joinpoint)、通知(Advice)、引入(Introduction)

    SpringAop注解,主要通过@AspectJ注解配置。

    需要新增两个AspectJ库:aspectjweaver.jar和aspectjrt.jar,还有一个依赖aopalliance.jar包。

    Aop注解配置如下:

    @Component
    @Aspect
    public class MyInterceptor {
        @Pointcut("execution (* cn.itcast.service.impl.UserServiceImpl.*(..))")
        private void cutMethod() {} // 声明一个切入点,cutMethod为切入点名称
        
        // 声明该方法是一个前置通知:在目标方法开始之前执行 
        @Before("cutMethod() && args(name)")
        public void doAccessCheck(String name) {
            System.out.println("前置通知:" + name);
        }
        
        @AfterReturning(pointcut="cutMethod()", returning="result")
        public void doAfterReturning(String result) {
            System.out.println("后置通知:" + result);
        }
        
        @After("cutMethod()")
        public void doAfter() {
            System.out.println("最终通知");
        }
        
        @AfterThrowing(pointcut="cutMethod()", throwing="e")
        public void doAfterThrowing(Exception e) {
            System.out.println("异常通知:" + e);
        }
        
    // 声明该方法是一个环绕通知,表示在目标方法前后执行设定的代码 @Around(
    "cutMethod()") public Object doBasicProfiling(ProceedingJoinPoint pjp) throws Throwable { /** * 环绕通知内部一定要确保执行该方法,如果不执行该方法,业务bean中被拦截的方法就不会被执行。 * 当执行该方法,如果后面还有切面的话,它的执行顺序应该是这样的:先执行后面的切面,如果后面没有切面了, * 再执行最终的目标对象的业务方法。若不执行该方法,则后面的切面,业务bean的方法都不会被执行。 */ System.out.println("进入方法"); Object result = pjp.proceed(); System.out.println("退出方法"); return result; } }

    具体的注解如下所示:

    @Aspect表明整个类是一个切面。

    @Component标记该类是一个组件,spring扫描注解配置时,会标记这些类要生成bean

    @Pointcut注解声明一个切入点。

    我们可利用方法签名来编写切入点表达式。

    最典型的切入点表达式是根据方法的签名来匹配各种方法:
    execution (* cn.itcast.service.impl.UserServiceImpl.*(..)):匹配UserServiceImpl类中声明的所有方法。第一个*代表任意修饰符及任意返回值类型,第二个*代表任意方法,..匹配任意数量任意类型的参数,若目标类与该切面在同一个包中,可以省略包名。
    execution public * cn.itcast.service.impl.UserServiceImpl.*(..):匹配UserServiceImpl类中的所有公有方法。
    execution public double cn.itcast.service.impl.UserServiceImpl.*(..):匹配UserServiceImpl类中返回值类型为double类型的所有公有方法。
    execution public double cn.itcast.service.impl.UserServiceImpl.*(double, ..):匹配UserServiceImpl类中第一个参数为double类型,后面不管有无参数的所有公有方法,并且该方法的返回值类型为double类型。
    execution public double cn.itcast.service.impl.UserServiceImpl.*(double, double):匹配UserServiceImpl类中参数类型为double,double类型的,并且返回值类型也为double类型的所有公有方法。

    前置通知:表示在目标方法之前执行设定的代码。

    环绕通知:表示在目标方法前后执行设定的代码。

     其他的源码如下:

    UserService.java如下:

    public interface UserService {
        public void save(String name);
        public void update(String name, Integer id);
        public String getUserName(Integer id);
    }

    UserServiceImpl.java如下:

    @Service
    public class UserServiceImpl implements UserService {
        @Override
        public void save(String name) {
    //        throw new RuntimeException("我是异常");
             System.out.println("我是save()方法");
        }
    
        @Override
        public void update(String name, Integer id) {
            System.out.println("我是update()方法");
        }
    
        @Override
        public String getUserName(Integer id) {
            System.out.println("我是getUserName()方法");
            return "xxx";
        }
    
    }

    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" xmlns:mvc="http://www.springframework.org/schema/mvc"
           xsi:schemaLocation="http://www.springframework.org/schema/beans
            http://www.springframework.org/schema/beans/spring-beans.xsd
            http://www.springframework.org/schema/context
            http://www.springframework.org/schema/context/spring-context-4.2.xsd
            http://www.springframework.org/schema/aop 
            http://www.springframework.org/schema/aop/spring-aop-4.2.xsd http://www.springframework.org/schema/mvc http://www.springframework.org/schema/mvc/spring-mvc.xsd">
        <!--开启aop代理-->
        <aop:aspectj-autoproxy />
        <!--扫描目录-->
        <context:component-scan base-package="cn.itcast.service"/>
    
        <!--开启注解驱动-->
        <mvc:annotation-driven/>
        <!--避免IE执行AJAX时,返回JSON出现下载文件 -->
        <bean id="mappingJacksonHttpMessageConverter"
              class="org.springframework.http.converter.json.MappingJacksonHttpMessageConverter">
            <property name="supportedMediaTypes">
                <list>
                    <value>text/html;charset=UTF-8</value>
                </list>
            </property>
        </bean>
        <!-- 启动SpringMVC的注解功能,完成请求和注解POJO的映射 -->
        <bean
                class="org.springframework.web.servlet.mvc.annotation.AnnotationMethodHandlerAdapter">
            <property name="messageConverters">
                <list>
                    <ref bean="mappingJacksonHttpMessageConverter" /> <!-- JSON转换器 -->
                </list>
            </property>
        </bean>
    </beans>

    最后,进行单元测试。UserServiceImplTest  如下所示:

    @RunWith(SpringJUnit4ClassRunner.class)
    @ContextConfiguration(locations={"classpath:beans.xml"})
    public class UserServiceImplTest {
        @Autowired
       private UserService userService;
    
    @Before
    public void before() throws Exception { 
    } 
    
    @After
    public void after() throws Exception { 
    } 
    
    /** 
    * 
    * Method: save(String name) 
    * 
    */ 
    @Test
    public void testSave() throws Exception { 
    //TODO: Test goes here...
        userService.save("lin");
    } 
    
    } 

    测试结果:

     

    参考博客:

    https://blog.csdn.net/yerenyuan_pku/article/details/52865330

  • 相关阅读:
    TMainMenu 类[三] 手动建立菜单(5) : 给菜单项添加事件
    TMainMenu 类[二] 成员列表
    TMainMenu 类[三] 手动建立菜单(4) : 添加分割线与隐藏多余的分割线
    初学 Delphi 嵌入汇编[30] 寄存器表
    TMainMenu 类[三] 手动建立菜单(6) : 更换菜单
    TMainMenu 类[三] 手动建立菜单(7) : 指定快捷键
    关于网络编程(服务端)的一些笔记 roen的专栏 博客频道 CSDN.NET
    关于 多进程epoll 与 “惊群”问题
    乱谈服务器编程 MrDB 博客园
    再谈select, iocp, epoll,kqueue及各种I/O复用机制 Shallway 博客频道 CSDN.NET
  • 原文地址:https://www.cnblogs.com/expiator/p/8872479.html
Copyright © 2011-2022 走看看