zoukankan      html  css  js  c++  java
  • 马士兵Spring-AOP-Aspect例子使用(1)

    一、例子1:                                                        

    1.工程结构:

    2.

    User.java:

    package com.cy.model;
    
    public class User {
        private String username;
        private String password;
        public String getUsername() {
            return username;
        }
        public void setUsername(String username) {
            this.username = username;
        }
        public String getPassword() {
            return password;
        }
        public void setPassword(String password) {
            this.password = password;
        }
    }
    View Code

    UserDAO.java:

    package com.cy.dao;
    
    import com.cy.model.User;
    
    public interface UserDAO {
        public void save(User user);
    }
    View Code

    UserDAOImpl.java:

    package com.cy.dao.impl;
    
    import org.springframework.stereotype.Component;
    
    import com.cy.dao.UserDAO;
    import com.cy.model.User;
    
    @Component
    public class UserDAOImpl implements UserDAO {
    
        public void save(User user) {
            //Hibernate
            //JDBC
            //XML
            //NetWork
            System.out.println("user saved!");
            //throw new RuntimeException("exeption!");
        }
    
    }
    View Code

    UserService.java:

    package com.cy.service;
    
    import javax.annotation.Resource;
    
    import org.springframework.stereotype.Component;
    
    import com.cy.dao.UserDAO;
    import com.cy.model.User;
    
    @Component("userService")
    public class UserService {
        
        @Resource
        private UserDAO userDAO;  
        
        public void init() {
            System.out.println("init");
        }
        
        public void add(User user) {
            userDAO.save(user);
        }
        
        
        public UserDAO getUserDAO() {
            return userDAO;
        }
        
        public void setUserDAO( UserDAO userDAO) {
            this.userDAO = userDAO;
        }
        
        public void destroy() {
            System.out.println("destroy");
        }
    }
    View Code

    LogInterceptor.java:

    package com.cy.aop;
    
    import org.aspectj.lang.annotation.Aspect;
    import org.aspectj.lang.annotation.Before;
    import org.springframework.stereotype.Component;
    
    @Aspect
    @Component
    public class LogInterceptor {
        
        /**
         * execution 专门的方法的切入语法;
         *               可以很方便的指定加到哪个/哪些方法上;
         * execution: 方法的执行;UserDAOImpl.save方法执行的时候;
         *               UserDAOImpl.save方法一执行,先把下面的方法before()加到前面 @Before
         */
        @Before("execution(public void com.cy.dao.impl.UserDAOImpl.save(com.cy.model.User))")
        public void before() {
            System.out.println("method before");
        }
    }

    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-2.5.xsd
               http://www.springframework.org/schema/context
               http://www.springframework.org/schema/context/spring-context-2.5.xsd
               http://www.springframework.org/schema/aop
               http://www.springframework.org/schema/aop/spring-aop-2.5.xsd">
               
        <context:annotation-config />
        <context:component-scan base-package="com.cy"/>
        
        <!-- 在spring容器的初始化过程中,会将com.cy下面的所有类都会扫描,
            扫描的时候发现@Component,将这个类初始化;
            同时发现@Aspect,发现这是一个切面逻辑,可以把它切到其他类的方法上面去;
                发现@Befored定义了下;在执行execution中的方法前面加入逻辑
         -->
        <aop:aspectj-autoproxy />
     
    </beans>

    测试代码:

    UserServiceTest.java:

    package com.cy.service;
    
    import org.junit.Test;
    import org.springframework.context.support.ClassPathXmlApplicationContext;
    
    import com.cy.model.User;
    
    public class UserServiceTest {
        
        @Test
        public void testAdd() throws Exception {
            ClassPathXmlApplicationContext ctx = new ClassPathXmlApplicationContext("beans.xml");
            UserService service = (UserService)ctx.getBean("userService");
            System.out.println(service.getClass());
            service.add(new User());
            ctx.destroy();
        }
    }

    运行结果:

    一些概念:                                                          

    二、例子2:                                                    

    1.一些织入点语法:

    1.the execution of any public method:
    execution(public * *(..))
    第1个*            任何返回值:
    第2个*             *(..)任何类的任何方法     
    
    2.the execution of any method with a name beginning with "set":
    execution(* set*(..))
     set*(..)        以set开头的任何方法
    
    3.the execution of any method defined by the AccountService interface:
    execution(* com.xyz.service.AccountService.*(..))
    任何返回值;
    com.xyz.service.AccountService类下面的任何方法;
    
    4.the execution of any method defined in the service package:
    execution(* com.xyz.service.*.*(..))
    
    5.the execution of any method defined in the service package or a sub-package:
    execution(* com.xyz.service..*.*(..))
    com.xyz.service下面的包,子包,不管子包多少层;里面的任何类任何方法;
    
    6.any join point (method execution only in Spring AOP) within the service package:
    within(com.xyz.service.*)
    method execution only in Spring AOP  spring自身也实现了一套AOP的语法;它也支持使用Aspect的语法来实现;
    大部分情况下用不到spring自身的AOP;
    View Code

    2.各种各样类型的Advice:

    1.Before advice
    
    2.After returning advice
    After returning advice runs when a matched method execution returns normally. It is declared using the @AfterReturning annotation:
    只要这个方法正常执行完了,会执行我们的AfterReturning
    如:
    @AfterReturning("com.xyz.myapp.SystemArchitecture.dataAccessOperation()")
    public void doAccessCheck() {
        // ...
     }
    
    3.After throwing advice
    After throwing advice runs when a matched method execution exits by throwing an exception. It is declared using the @AfterThrowing annotation:
    当一个方法执行抛出异常的时候,抛出了任何异常,就会执行@AfterThrowing
    如:
    @AfterThrowing("com.xyz.myapp.SystemArchitecture.dataAccessOperation()")
    public void doRecoveryActions() {
        // ...
      }
    
    4.After (finally) advice
    执行你的方法时候是写try catch finally;catch到异常的时候是执行@AfterThrowing;最后一定会执行finally;
    
    5.Around advice
    around环绕;前面可以加逻辑,后面也可以加逻辑;
    如:
    import org.aspectj.lang.annotation.Aspect;
    import org.aspectj.lang.annotation.Around;
    import org.aspectj.lang.ProceedingJoinPoint;
    @Aspect
    public class AroundExample {
    
      @Around("com.xyz.myapp.SystemArchitecture.businessService()")
      public Object doBasicProfiling(ProceedingJoinPoint pjp) throws Throwable {
        // start stopwatch  加了自己的逻辑;
        Object retVal = pjp.proceed();        //想让程序继续执行,必须调pjp.proceed(),程序才会继续运行;可以参考责任链设计模式;
       //struts2的Interceptor也是这么用的;
        // stop stopwatch  后面加自己的逻辑
        return retVal;
      }
    }
    View Code

    使用例子1:

    LogInterceptor.java:

    package com.cy.aop;
    
    import org.aspectj.lang.annotation.AfterReturning;
    import org.aspectj.lang.annotation.Aspect;
    import org.aspectj.lang.annotation.Before;
    import org.springframework.stereotype.Component;
    
    @Aspect
    @Component
    public class LogInterceptor {
        
        /**
         * execution    方法运行
         * com.cy.dao下面包括它的子包下面,任何类的任何方法;返回值任何类型
         */
        @Before("execution(public * com.cy.dao..*.*(..))")
        public void before() {
            System.out.println("method before");
        }
        
        
        /**
         * @AfterReturning 方法正常执行完成之后
         * 
         */
        @AfterReturning("execution(public * com.cy.dao..*.*(..))")
        public void afterReturning() {
            System.out.println("method after returning");
        }
        
    }

    运行UserServiceTest.java:---  console:

    使用例子2:afterThrowing:

    LogInterceptor.java:

    package com.cy.aop;
    
    import org.aspectj.lang.annotation.AfterReturning;
    import org.aspectj.lang.annotation.AfterThrowing;
    import org.aspectj.lang.annotation.Aspect;
    import org.aspectj.lang.annotation.Before;
    import org.aspectj.lang.annotation.Pointcut;
    import org.springframework.stereotype.Component;
    
    @Aspect
    @Component
    public class LogInterceptor {
        
        @Before("execution(public * com.cy.dao..*.*(..))")
        public void before() {
            System.out.println("method before");
        }
        
        @AfterThrowing("execution(public * com.cy.dao..*.*(..))")
        public void afterThrowing() {
            System.out.println("method after throwing");
        }
    
    }
    View Code

    UserDAOImpl.java中手动抛出一个异常:

    @Component
    public class UserDAOImpl implements UserDAO {
    
        public void save(User user) {
            //Hibernate
            //JDBC
            //XML
            //NetWork
            System.out.println("user saved!");
            throw new RuntimeException("exeption!");
        }
    
    }
    View Code

    console:

    使用例子3:@Around:

    LogInterceptor.java:

    package com.cy.aop;
    
    import org.aspectj.lang.ProceedingJoinPoint;
    import org.aspectj.lang.annotation.AfterReturning;
    import org.aspectj.lang.annotation.AfterThrowing;
    import org.aspectj.lang.annotation.Around;
    import org.aspectj.lang.annotation.Aspect;
    import org.aspectj.lang.annotation.Before;
    import org.aspectj.lang.annotation.Pointcut;
    import org.springframework.stereotype.Component;
    
    @Aspect
    @Component
    public class LogInterceptor {
        
        @Before("execution(public * com.cy.dao..*.*(..))")
        public void before() {
            System.out.println("method before");
        }
        
        @Around("execution(public * com.cy.dao..*.*(..))")
        public void aroundMethod(ProceedingJoinPoint pjp) throws Throwable {
            System.out.println("method around start");
            pjp.proceed();
            System.out.println("method around end");
        }
    
    }
    View Code

    console:

    使用例子4:

    把切点定义到UserService.java中的add方法上:

    LogInterceptor.java:

    package com.cy.aop;
    
    import org.aspectj.lang.ProceedingJoinPoint;
    import org.aspectj.lang.annotation.AfterReturning;
    import org.aspectj.lang.annotation.AfterThrowing;
    import org.aspectj.lang.annotation.Around;
    import org.aspectj.lang.annotation.Aspect;
    import org.aspectj.lang.annotation.Before;
    import org.aspectj.lang.annotation.Pointcut;
    import org.springframework.stereotype.Component;
    
    @Aspect
    @Component
    public class LogInterceptor {
        
        @Before("execution(public * com.cy.service..*.add(..))")
        public void before() {
            System.out.println("method before");
        }
        
        @Around("execution(public * com.cy.dao..*.*(..))")
        public void aroundMethod(ProceedingJoinPoint pjp) throws Throwable {
            System.out.println("method around start");
            pjp.proceed();
            System.out.println("method around end");
        }
    
    }
    View Code

    运行junit但是报错了:

    org.springframework.beans.factory.BeanCreationException: Error creating bean with name 'userService' defined in file [E:jdbcWorkspacespring_aopincomcyserviceUserService.class]: Initialization of bean failed; nested exception is org.springframework.aop.framework.AopConfigException: Cannot proxy target class because CGLIB2 is not available. Add CGLIB to the class path or specify proxy interfaces.
    因为UserService没有实现接口;
    一个类如果实现了接口,spring采用jdk自带的Proxy和InvocationHandler来产生动态代理;
    这个类如果没有实现接口,它会用直接操作二进制码的类库,也就是CGLIB来帮你产生代理的代码;
     
    加入CGLIB的jar包:
     
    console:
     
  • 相关阅读:
    A Famous City
    A Famous ICPC Team
    配置单元测试环境,找不到SenTestingKit
    linux解压.tar命令
    语音输入——科大讯飞
    查看dsym错误信息
    工程里关闭arc
    导入签名错误
    mac显示隐藏文件
    类uialertview弹出动画
  • 原文地址:https://www.cnblogs.com/tenWood/p/6810855.html
Copyright © 2011-2022 走看看