SpringAOP第一个案例

Posted 入道弥深,所见弥大

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了SpringAOP第一个案例相关的知识,希望对你有一定的参考价值。

1.Aop解决的问题

  • 当需要为多个不具有继承关系的对象引入同一个公共行为时,例如日志、安全检测等,我们只有在每个对象里引用公共行为,比如打印日志,这样程序中就产生了大量的重复代码,程序就不便于维护了,所以就有了一个对面向对象编程的补充,即面向方面编程(AOP),AOP所关注的方向是横向的,不同于OOP的纵向。
    2.Aop的实现方式
  • 静态 AOP 实现, AOP 框架在编译阶段对程序源代码进行修改,生成了静态的 AOP 代理类(生成的 *.class 文件已经被改掉了,需要使用特定的编译器),比如 AspectJ。
  • 动态 AOP 实现, AOP 框架在运行阶段对动态生成代理对象(在内存中以 JDK 动态代理,或 CGlib 动态地生成 AOP 代理类),如 SpringAOP。

3.Aop的专有名词

  • 通知(Advice): AOP 框架中的增强处理。通知描述了切面何时执行以及如何执行增强处理。
  • 连接点(join point): 连接点表示应用执行过程中能够插入切面的一个点,这个点可以是方法的调用、异常的抛出。在 Spring AOP 中,连接点总是方法的调用。
  • 切点(PointCut): 可以插入增强处理的连接点。
  • 切面(Aspect): 切面是通知和切点的结合。
  • 引入(Introduction):引入允许我们向现有的类添加新的方法或者属性。
  • 织入(Weaving): 将增强处理添加到目标对象中,并创建一个被增强的对象,这个过程就是织入。
    4.第一个动态Aop实例:例如SSM框架中,Service层会有一些业务比如常见的增删改查,例如现在需要在插入数据成功之后打印下日志
  • 引入依赖类AspectJ
        <dependency>
            <groupId>org.aspectj</groupId>
            <artifactId>aspectjrt</artifactId>
            <version>1.9.2</version>
        </dependency>
        <dependency>
            <groupId>org.aspectj</groupId>
            <artifactId>aspectjweaver</artifactId>
            <version>1.9.2</version>
        </dependency>
  • 创建要增强的行为:Service接口的实现类调mapper接口插入数据
public interface UserService {
    int insertUser();
    int update(SuperUser user);
}
/**
 * @author ngLeede
 * @version 1.0
 * @Desc service的实现类
 * @date 2021/6/10 22:07
 */
public class UserServiceImpl implements UserService {
    
    private UserMapper userMapper;
    
    public UserMapper getUserMapper() {
        return userMapper;
    }
    
    public void setUserMapper(UserMapper userMapper) {
        this.userMapper = userMapper;
    }
    
    @Override
    public int insertUser() {
        userMapper.insertUser();
        return 0;
    }
    
    @Override
    public int update(SuperUser user) {
        userMapper.update(user);
        return 0;
    }
}
/**
 * @desc mapper接口
 * @author ngLeede
 * @date 2021/6/11 22:27
 */
public interface UserMapper {
    int insertUser();
    
    void update(SuperUser user);
}
/**
 * @author ngLeede
 * @version 1.0
 * @Desc mapper接口的实现类,对应的行为是SSM框架里的mapper.xml 
 * @date 2021/6/10 22:06
 */
public class UserMapperImpl implements UserMapper {
    @Override
    public int insertUser() {
        System.out.println("--插入数据--mapper接口--");
        return 0;
    }
    
    @Override
    public void update(SuperUser user) {
        System.out.println("---修改超人信息---");
    }
}
  • 创建增强类实现aop的MethodBeforeAdvice 前置方法增强--具体要实现的功能是在调用Service层的方法前打印日志
/**
 * @author ngLeede
 * @version 1.0
 * @Desc 增强类
 * @date 2021/6/10 22:46
 */
public class MyAdvice implements MethodBeforeAdvice {
    @Override
    public void before(Method method, Object[] objects, Object o) throws Throwable {
        String mt = method.getName();
        System.out.println("前置增强"+mt+"方法");
    }
}
  • 配置切点使前置增强方法能够作用于Service层的方法,在applicationContext.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:aop="http://www.springframework.org/schema/aop"
       xsi:schemaLocation="http://www.springframework.org/schema/beans
                    http://www.springframework.org/schema/beans/spring-beans.xsd
                    http://www.springframework.org/schema/aop
                    http://www.springframework.org/schema/aop/spring-aop.xsd">
    <!--第一个aopyi 实例-->
    <bean id="userMapper" class="com.ngLeede.aopyi.mapper.impl.UserMapperImpl"></bean>
    <bean id="userService" class="com.ngLeede.aopyi.service.impl.UserServiceImpl">
        <property name="userMapper" ref="userMapper" />
    </bean>
    <bean id="myadvice" class="com.ngLeede.aopyi.advice.MyAdvice"></bean>
    <aop:config>
        <!--切点表达式 增强service下的方法-->
        <aop:pointcut id="ponitcut" expression="execution(* com.ngLeede.aopyi.service.*.*(..))"/>
        <!--织入-->
        <aop:advisor advice-ref="myadvice" pointcut-ref="ponitcut"/>
    </aop:config>
</beans>
  • 简单的测试
public class AppTest 
{
    /**
     * @desc 測試第一Aop實例
     * @author ngLeede
     * @date 2021/6/10 22:12
     */
    @Test
    public void testAopyi(){
        ApplicationContext applicationContext = new ClassPathXmlApplicationContext("applicationContext.xml");
        UserService userService = (UserService) applicationContext.getBean("userService");
        userService.insertUser();
        SuperUser user = new SuperUser();
        user.setName("超人");
        user.setPhone("167777");
        userService.update(user);
        
    }
}

以上是关于SpringAOP第一个案例的主要内容,如果未能解决你的问题,请参考以下文章

Spring AOP 实现方式与应用

Reload Activity 以在 Fragment 之间重新切换

Spring源码高级笔记之——Spring AOP应用

Android 7 上的 VideoView 错误

图文并茂!!!一文搞懂SpringAOP(面向切面编程)

图文并茂!!!一文搞懂SpringAOP(面向切面编程)