zoukankan      html  css  js  c++  java
  • spring AOP简单入门

    AOP(aspect oriented programming)面向切面编程。

    大致意思是在方法的执行过程中织入其他要执行的方法。

    项目结构图

    先介绍一下通过代理的方式实现aop,几个文件和上一篇一样,再贴一遍方便观看

    package com.ouc.wkp.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;
        }
    }
    User.java
    package com.ouc.wkp.dao;
    
    import com.ouc.wkp.model.User;
    
    public interface UserDAO {
        public void save(User user);
        public void delete();
    }
    UserDAO.java
    package com.ouc.wkp.dao.impl;
    
    import org.springframework.stereotype.Component;
    
    import com.ouc.wkp.dao.UserDAO;
    import com.ouc.wkp.model.User;
    
    @Component("u")
    public class UserDAOImpl implements UserDAO {
    
        @Override
        public void save(User user) {
            // Hibernate
            // JDBC
            // XML
            // NetWork
            System.out.println("user saved!");
    //        throw new RuntimeException();
        }
    
        @Override
        public void delete() {
            // TODO Auto-generated method stub
            
        }
    
    }
    UserDAOImpl.java
    package com.ouc.wkp.service;
    
    import javax.annotation.PostConstruct;
    import javax.annotation.PreDestroy;
    import javax.annotation.Resource;
    
    import org.springframework.beans.factory.annotation.Autowired;
    import org.springframework.beans.factory.annotation.Qualifier;
    import org.springframework.stereotype.Component;
    
    import com.ouc.wkp.dao.UserDAO;
    import com.ouc.wkp.model.User;
    
    @Component("userService")
    public class UserService {
    
        private UserDAO userDAO;
    
        @PostConstruct
        public void init() {
            System.out.println("init");
        }
    
        public void add(User user) {
            userDAO.save(user);
        }
    
        public UserDAO getUserDAO() {
            return userDAO;
        }
    
        // @Autowired @Qualifier("u")
        @Resource(name = "u")
        public void setUserDAO(UserDAO userDAO) {
            this.userDAO = userDAO;
        }
    
        @PreDestroy
        public void destroy() {
            System.out.println("destroy");
        }
    }
    UserService.java

    然后是一个代理类,继承自InvocationHandler

    package com.ouc.wkp.aop;
    
    import java.lang.reflect.InvocationHandler;
    import java.lang.reflect.Method;
    
    public class LogIntercepter implements InvocationHandler{
        private Object target;
    
        public Object getTarget() {
            return target;
        }
    
        public void setTarget(Object target) {
            this.target = target;
        }
        
        public void beforeMethod(Method m){
            System.out.println(m.getName()+" start");
        }
        
        public void afterMethod(Method m){
            System.out.println(m.getName()+" end");
        }
        
        public Object invoke(Object proxy,Method m,Object[] args) throws Throwable{
            beforeMethod(m);
            m.invoke(target, args);
            afterMethod(m);
            return null;
        }
    }
    LogIntercepter.java

    然后再测试类中进行如下调用

    @Test
        public void testProxy() {
            UserDAO userDAO = new UserDAOImpl();
            LogIntercepter li = new LogIntercepter();
            li.setTarget(userDAO); 
            UserDAO userDAOProxy = (UserDAO) Proxy.newProxyInstance(userDAO
                    .getClass().getClassLoader(), userDAO.getClass()
                    .getInterfaces(), li);
            System.out.println(userDAOProxy.getClass());
            userDAOProxy.delete();
            userDAOProxy.save(new User());
        }
    UserServiceTest.java

    运行结果

    然后介绍通过xml配置文件实现aop

     使用aop需要一下 
     xmlns:aop="http://www.springframework.org/schema/aop" 
     http://www.springframework.org/schema/aop -->
     http://www.springframework.org/schema/aop/spring-aop-2.5.xsd"> 
     <aop:aspectj-autoproxy /> 

    还需要这个开启对com.ouc.wkp包下面的扫描

    <context:component-scan base-package="com.ouc.wkp"></context:component-scan>

    <?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-3.1.xsd
                http://www.springframework.org/schema/context
                http://www.springframework.org/schema/context/spring-context-3.1.xsd
                http://www.springframework.org/schema/aop
                http://www.springframework.org/schema/aop/spring-aop-3.1.xsd">
        <context:annotation-config />
        <!-- 使用注解需要下面四条 -->
        <!-- xmlns:context="http://www.springframework.org/schema/context" -->
        <!-- http://www.springframework.org/schema/context -->
        <!-- http://www.springframework.org/schema/context/spring-context-3.1.xsd"> -->
        <!-- <context:annotation-config /> -->
    
        <!-- 使用aop需要一下 -->
        <!-- xmlns:aop="http://www.springframework.org/schema/aop" -->
        <!-- http://www.springframework.org/schema/aop -->
        <!-- http://www.springframework.org/schema/aop/spring-aop-2.5.xsd"> -->
        <!-- <aop:aspectj-autoproxy /> -->
    
        <!-- 扫描 -->
        <context:component-scan base-package="com.ouc.wkp"></context:component-scan>
    
        <aop:aspectj-autoproxy />
    
        <bean id="logIntercepter2" class="com.ouc.wkp.aop.LogIntercepter2"></bean>
        <aop:config>
            <!-- <aop:pointcut expression="execution(public * com.ouc.wkp.service..*.add(..))" 
                id="servicePointcut"/> -->
            <!-- <aop:aspect id="logAspect" ref="logIntercepter"> -->
            <!-- <aop:before method="before" pointcut="servicePointcut"/> -->
            <!-- </aop:aspect> -->
            <aop:aspect id="logAspect" ref="logIntercepter2">
                <aop:before method="before"
                    pointcut="execution(public * com.ouc.wkp.service..*.add(..))" />
            </aop:aspect>
        </aop:config>
    </beans>
    beans.xml

    <bean id="logIntercepter2" class="com.ouc.wkp.aop.LogIntercepter2"></bean>
    <aop:config>
    <!-- <aop:pointcut expression="execution(public * com.ouc.wkp.service..*.add(..))"
    id="servicePointcut"/> -->
    <!-- <aop:aspect id="logAspect" ref="logIntercepter"> -->
    <!-- <aop:before method="before" pointcut="servicePointcut"/> -->
    <!-- </aop:aspect> -->
    <aop:aspect id="logAspect" ref="logIntercepter2">
    <aop:before method="before"
    pointcut="execution(public * com.ouc.wkp.service..*.add(..))" />
    </aop:aspect>
    </aop:config>

    看下面这段 第一行声明了一个代理切入类(表达不准确)

    <aop:pointcut expression="execution(public * com.ouc.wkp.service..*.add(..))" 
    id="servicePointcut"/>标识定义一个切入点pointcut。

    <aop:before method="before" pointcut="servicePointcut"/>表示before织入这个切入点。

    execution(public * com.ouc.wkp.service..*.add(..))代表com.ouc.wkp.service包下的任意包的任意类的add方法。

    然后我们看代理切入类

    package com.ouc.wkp.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 LogIntercepter2 {
    //    @Pointcut("execution(public * com.ouc.wkp.service..*.add(..))")
        public void myMethod(){};
                
    //    @Before("myMethod()")
        public void before() {
            System.out.println("method before");
        }
        
    //    @AfterReturning("execution(public * com.ouc.wkp.dao..*.*(..))")
        public void afterReturning(){
            System.out.println("method after returning");
        }
        
    //    @AfterThrowing("myMethod()")
        public void afterThrowing(){
            System.out.println("method after throwing");
        }
        
    //    @Around("myMethod()")
        public void aroundMethod(ProceedingJoinPoint pjp) throws Throwable{
            System.out.println("method around start");
            pjp.proceed();
            System.out.println("method around end");
        }
    }
    LogIntercepter2.java

    类的开头需要加上

    @Aspect
    @Component

    测试方法

    @Test
        public void testAdd() throws Exception {
            ClassPathXmlApplicationContext ctx = new ClassPathXmlApplicationContext(
                    "beans.xml");
    
            UserService service = (UserService) ctx.getBean("userService");
            User user = new User();
            user.setUsername("qqq");
            user.setPassword("123ppp");
            //是一个代理
            System.out.println(service.getClass());
            service.add(user);
    
            ctx.destroy();
    
        }
    UserServiceTest.java

    运行结果

    我们看到我们获得的userservice实质上是一个代理类

    最后介绍通过注解实现aop,LogIntercepter2的代码再贴一遍.

    beans.xml里面的<aop:config>可以注释掉

    package com.ouc.wkp.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 LogIntercepter2 {
        @Pointcut("execution(public * com.ouc.wkp.service..*.add(..))")
        public void myMethod(){};
                
        @Before("myMethod()")
        public void before() {
            System.out.println("method before");
        }
        
        @AfterReturning("execution(public * com.ouc.wkp.dao..*.*(..))")
        public void afterReturning(){
            System.out.println("method after returning");
        }
        
        @AfterThrowing("myMethod()")
        public void afterThrowing(){
            System.out.println("method after throwing");
        }
        
        @Around("myMethod()")
        public void aroundMethod(ProceedingJoinPoint pjp) throws Throwable{
            System.out.println("method around start");
            pjp.proceed();
            System.out.println("method around end");
        }
    }
    LogIntercepter2.java

    @Pointcut("execution(public * com.ouc.wkp.service..*.add(..))")

    public void myMethod(){};表示定义一个切入点

    @Before("myMethod()")表示在方法执行前执行注解下面的方法  myMethod()为上面定义的切入点

    后面的注解见名知意

    运行结果

    感觉还是很神奇的 以前一直不理解什么是面向切面。现在简单了解了一下觉得很有趣,但是还是无法用语言准确表达出来= =

    下一篇介绍spring整合hibernate

  • 相关阅读:
    opencv_图像的色彩空間cvtColor(HSV、HSL、HSB )及相关色彩学
    ASCII码字符对照表
    机器学习_logistic回归和梯度下降
    mysql 安装异常:this application requires .NET Framework(尚未安装.NET Framework 4.5 原因是:指定)
    面向对象的基本原则----
    面试题:“你能不能谈谈,java GC是在什么时候,对什么东西,做了什么事情?”
    String 解析--创建对象存储分析
    <cache> does not allow attribute "maxBytesLocalDisk
    Your 30-day trial of MyEclipse has expired 解决方案
    svn: E175002: java.lang.RuntimeException: Could not generate DH keypair svn: E175002: OPTIONS request failed on '/svn/ERPHR/HR_633'
  • 原文地址:https://www.cnblogs.com/wangkaipeng/p/5780422.html
Copyright © 2011-2022 走看看