美文网首页
day11 Spring AOP

day11 Spring AOP

作者: 老婆日向雏田 | 来源:发表于2019-04-16 12:15 被阅读0次

    AOP (Aspect Oriented Programming)面向切面编程
    OOP(Oriented Oriented Programming)面向对象编程
    通过OOP的纵向和AOP的横向抽取,程序才可以真正解决问题
    AOP的使用场景:日志 事务

    AOP基本上是通过代理机制实现的

    • 单例模式
    • 代理
    • 工厂
    • 装饰器
    • 适配器
      代理的对象为接口

    AOP中一些概念的理解

    • aop adviser:切面
    • aop aspect:切面配置
    • aop pointuct:切点
    • adviser=advice+pointuct即切面=增强+切点(在哪里做什么)

    Hello前置增强练习

    • 给pom文件中添加aop依赖
    <?xml version="1.0" encoding="UTF-8"?>
    
    <project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
      xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
      <modelVersion>4.0.0</modelVersion>
    
      <groupId>com.spring</groupId>
      <artifactId>AOP</artifactId>
      <version>1.0-SNAPSHOT</version>
    
      <name>AOP</name>
      <!-- FIXME change it to the project's website -->
      <url>http://www.example.com</url>
    
      <properties>
        <project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
        <maven.compiler.source>1.8</maven.compiler.source>
        <maven.compiler.target>1.8</maven.compiler.target>
        <spring.version>5.0.10.RELEASE</spring.version>
        <aspectj.version>1.9.2</aspectj.version>
        <junit.version>4.12</junit.version>
        <log4j.version>1.2.17</log4j.version>
        <slf4j.version>1.7.12</slf4j.version>
      </properties>
    
      <dependencies>
        <dependency>
          <groupId>junit</groupId>
          <artifactId>junit</artifactId>
          <version>4.12</version>
          <scope>test</scope>
        </dependency>
        <!-- <spring-test依赖>-->
        <dependency>
          <groupId>org.springframework</groupId>
          <artifactId>spring-test</artifactId>
          <version>${spring.version}</version>
        </dependency>
    
        <!--spring-context依赖-->
        <dependency>
          <groupId>org.springframework</groupId>
          <artifactId>spring-context</artifactId>
          <version>${spring.version}</version>
        </dependency>
        <!--spring-aop依赖-->
        <dependency>
          <groupId>org.springframework</groupId>
          <artifactId>spring-aop</artifactId>
          <version>${spring.version}</version>
        </dependency>
        <!--aspectj依赖-->
        <dependency>
          <groupId>org.aspectj</groupId>
          <artifactId>aspectjrt</artifactId>
          <version>${aspectj.version}</version>
        </dependency>
        <dependency>
          <groupId>org.aspectj</groupId>
          <artifactId>aspectjweaver</artifactId>
          <version>${aspectj.version}</version>
        </dependency>
        <!--Lombok依赖-->
        <dependency>
          <groupId>org.projectlombok</groupId>
          <artifactId>lombok</artifactId>
          <version>1.16.18</version>
        </dependency>
        <!-- log4j日志依赖 -->
        <dependency>
          <groupId>org.slf4j</groupId>
          <artifactId>slf4j-api</artifactId>
          <version>1.6.6</version>
        </dependency>
        <dependency>
          <groupId>org.slf4j</groupId>
          <artifactId>slf4j-log4j12</artifactId>
          <version>1.6.6</version>
        </dependency>
      </dependencies>
    
      <build>
        <pluginManagement><!-- lock down plugins versions to avoid using Maven defaults (may be moved to parent pom) -->
          <plugins>
            <!-- clean lifecycle, see https://maven.apache.org/ref/current/maven-core/lifecycles.html#clean_Lifecycle -->
            <plugin>
              <artifactId>maven-clean-plugin</artifactId>
              <version>3.1.0</version>
            </plugin>
            <!-- default lifecycle, jar packaging: see https://maven.apache.org/ref/current/maven-core/default-bindings.html#Plugin_bindings_for_jar_packaging -->
            <plugin>
              <artifactId>maven-resources-plugin</artifactId>
              <version>3.0.2</version>
            </plugin>
            <plugin>
              <artifactId>maven-compiler-plugin</artifactId>
              <version>3.8.0</version>
            </plugin>
            <plugin>
              <artifactId>maven-surefire-plugin</artifactId>
              <version>2.22.1</version>
            </plugin>
            <plugin>
              <artifactId>maven-jar-plugin</artifactId>
              <version>3.0.2</version>
            </plugin>
            <plugin>
              <artifactId>maven-install-plugin</artifactId>
              <version>2.5.2</version>
            </plugin>
            <plugin>
              <artifactId>maven-deploy-plugin</artifactId>
              <version>2.8.2</version>
            </plugin>
            <!-- site lifecycle, see https://maven.apache.org/ref/current/maven-core/lifecycles.html#site_Lifecycle -->
            <plugin>
              <artifactId>maven-site-plugin</artifactId>
              <version>3.7.1</version>
            </plugin>
            <plugin>
              <artifactId>maven-project-info-reports-plugin</artifactId>
              <version>3.0.0</version>
            </plugin>
          </plugins>
        </pluginManagement>
      </build>
    </project>
    
    • Hello接口及实现接口中方法的HelloImpl类
    package com.spring;
    
    public interface Hello {
        String getHello();
    }
    
    
    package com.spring;
    
    public class HelloImpl implements Hello {
        @Override
        public String getHello() {
            return "Hello,Spring AOP";
        }
    }
    
    • 用户自定义的前置增强类MyBeforeAdvicelei
    package com.spring;
    
    import org.slf4j.Logger;
    import org.slf4j.LoggerFactory;
    
    /*
     * 用户自定义的前置增强类
     * */
    public class MyBeforeAdvice {
        private  static final Logger logger= LoggerFactory.getLogger(MyBeforeAdvice.class);
        /*定义前置方法*/
        public void beforeMethod() {
            logger.info("This is a before method by wxy");
            logger.debug("This is a before method by wxy");
    
    
           // System.out.println("This is a before methoad");
        }
    
    }
    
    • 配置文件
    <!--配置一个Hello的bean  等同于Hello hello = new HelloImpl();-->
       <bean id="hello" class="com.spring.HelloImpl"/>
           <!--配置一个MyBeforeAdvice前置增强的bean-->
           <bean id="mybeforeAdvice" class="com.spring.MyBeforeAdvice"/>
        <!--配置Aop-->
        <aop:config>
            <aop:aspect id="before" ref="mybeforeAdvice">
                <aop:pointcut id="myPointcut" expression="execution(* com.spring.*.*(..))"/>
                <aop:before method="beforeMethod" pointcut-ref="myPointcut"/>
            </aop:aspect>
        </aop:config>
    
    • 主类
    package com.spring;
    
    import javafx.application.Application;
    import org.springframework.context.ApplicationContext;
    import org.springframework.context.support.ClassPathXmlApplicationContext;
    
    public class HelloApp {
        public static void main(String[] args) {
            ApplicationContext context = new ClassPathXmlApplicationContext("/bean.xml");
            Hello hello = context .getBean(Hello.class);
            System.out.println(hello.getHello());
        }
    
    }
    
    • 运行结果

    实战:模仿连接数据库的操作

    • UserDao接口
    package com.spring;
    
    public interface UserDao {
        void insert();
    }
    
    
    

    -UserDaoImpl类

    package com.spring;
    
    import org.slf4j.Logger;
    import org.slf4j.LoggerFactory;
    
    public class UserDaoImpl implements UserDao {
        private static final Logger logger= LoggerFactory.getLogger(UserDaoImpl.class);
        @Override
        public void insert() {
            logger.info("开始插入一条数据。。。");
        }
    }
    
    
    • MyBeforeAdvice前置增强类
    package com.spring;
    
    import org.slf4j.Logger;
    import org.slf4j.LoggerFactory;
    
    /*
     * 用户自定义的前置增强类
     * */
    public class MyBeforeAdvice {
        private  static final Logger logger= LoggerFactory.getLogger(MyBeforeAdvice.class);
        /*定义前置方法*/
        public void beforeMethod() {
            logger.info("This is a before method by wxy");
            logger.debug("This is a before method by wxy");
    
    
           // System.out.println("This is a before methoad");
        }
    
    }
    
    
    • 配置文件
    <bean id="userDao" class="com.spring.UserDaoImpl"/>
        <bean id="beforeAdvice" class="com.spring.BeforeAdvice"/>
        <aop:config>
            <aop:aspect id="before1" ref="beforeAdvice">
                <aop:pointcut id="myPointcut1" expression="execution(* com.spring.*.*(..))"/>
                <aop:before method="connectDB" pointcut-ref="myPointcut1"/>
            </aop:aspect>
        </aop:config>
    
    • UserDao单元测试类
    package com.spring;
    
    import org.junit.Test;
    import org.junit.runner.RunWith;
    import org.springframework.beans.factory.annotation.Autowired;
    import org.springframework.test.context.ContextConfiguration;
    import org.springframework.test.context.junit4.SpringJUnit4ClassRunner;
    
    import static org.junit.Assert.*;
    @RunWith(SpringJUnit4ClassRunner.class)
    @ContextConfiguration(locations = {"/bean.xml"})
    public class UserDaoTest {
        @Autowired
        private UserDao userDao;
        @Test
        public void insert(){
            userDao.insert();
        }
    
    }
    
    • 运行结果


      Snipaste_2019-03-10_10-36-10.png

    实战:使用@AspectJ的例子

    • 此例是演绎了一段“武松打虎”的情节——武松(Fighter)在山里等着老虎(Tiger)出现,只要发现老虎出来,就打老虎

    1.定义业务类型

    • 老虎(Tiger)类
    package com.spring;
    
    public class Tiger {
    
        public void walk(){
            System.out.println("Tiger is walking...");
        }
    
    }
    
    

    2.定义切面和配置

    • 武松(Fighter)类
    package com.spring;
    
    import org.aspectj.lang.annotation.AfterReturning;
    import org.aspectj.lang.annotation.Aspect;
    import org.aspectj.lang.annotation.Before;
    import org.aspectj.lang.annotation.Pointcut;
    
    @Aspect
    public class Fighter {
        @Pointcut("execution(* com.spring.Tiger.walk())")
        public void foundTiger(){
    
        }
        @Before(value = "foundTiger()")
        public void foundBefore(){
            System.out.println("Fighter wait for tiger...");
        }
    
        @AfterReturning("foundTiger()")
        public void foundAfter(){
            System.out.println("Fighter flight with tiger...");
        }
    }
    
    
    • 相应的Spring配置
    <!--启动AspectJ支持-->
        <aop:aspectj-autoproxy/>
        <!--定义bean-->
        <bean id="fighter " class="com.spring.Fighter"/>
        <bean id="tiger" class="com.spring.Tiger"/>
    

    3.定义主应用

    • 主应用定义为
    package com.spring;
    
    import org.springframework.context.ApplicationContext;
    import org.springframework.context.support.ClassPathXmlApplicationContext;
    
    public class Application {
        public static void main(String[] args) {
            @SuppressWarnings("resources")
            ApplicationContext context = new ClassPathXmlApplicationContext("bean.xml");
            Tiger tiger= context.getBean(Tiger.class);
            tiger.walk();
        }
    }
    

    4.运行

    运行结果.png
    本篇笔记出处@七夏港_f3ef

    相关文章

      网友评论

          本文标题:day11 Spring AOP

          本文链接:https://www.haomeiwen.com/subject/huggwqtx.html