1. 程式人生 > 其它 >SpringAOP第一個案例

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);
        
    }
}