spring總結————AOP面向切面java
spring aop面向切面編程,java是面向對象的語言。面試
真正的service層代碼spring
業務邏輯層再處理業務以前和以後都要進行一些參數的校驗,異常處理,日誌記錄等代碼。有很是多很是核心的業務邏輯在裏面,這些業務邏輯不要是不行的。怎麼解決這種問題?生活中有不少這樣的例子,實際上就是使用了代理模式來解決這個問題。spring aop 就是基於代理模式的。代理分靜態代理和動態代理,spring aop的核心就是經過動態代理來實現的。express
第一步,建立spring項目 引入jar包編程
第二步,建立主配置文件設計模式
1 <?xml version="1.0" encoding="UTF-8"?> 2 <beans xmlns="http://www.springframework.org/schema/beans" 3 xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" 4 xmlns:context="http://www.springframework.org/schema/context" 5 xsi:schemaLocation="http://www.springframework.org/schema/beans 6 http://www.springframework.org/schema/beans/spring-beans.xsd 7 http://www.springframework.org/schema/context http://www.springframework.org/schema/context/spring context.xsd"> 8 <bean id="userService" class="com.aaa.spring.service.impl.UserServiceImpl"></bean> 9 </beans>
第三步,建立包實體類app
注:service層只保留核心的業務邏輯代碼:ide
1 package com.aaa.spring.service.impl; 2 import com.aaa.spring.entity.Userimport com.aaa.spring.service.UserService/** 3 * 用戶管理service實現類 4 */ 5 public class UserServiceImpl implements UserService { 6 @Override 7 public void saveUser(User user) { 8 System.out.println("保存用戶"); 9 } 10 @Override 11 public void deleteUser(User user) { 12 System.out.println("刪除用戶"); 13 } 14 @Overridepublic void updateUser(User user) { 15 System.out.println("修改用戶"); 16 } 17 @Override 18 public User findById(Long id) { 19 System.out.println("根據id查找用戶"); 20 return null; 21 } 22 }
第四步,在spring的主配置文件中配置bean測試
1 <?xml version="1.0" encoding="UTF-8"?> 2 <beans xmlns="http://www.springframework.org/schema/beans" 3 xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" 4 xmlns:context="http://www.springframework.org/schema/context" 5 xsi:schemaLocation="http://www.springframework.org/schema/beans 6 http://www.springframework.org/schema/beans/spring-beans.xsd 7 http://www.springframework.org/schema/context http://www.springframework.org/schema/context/spring context.xsd"> 8 <bean id="userService" class="com.aaa.spring.service.impl.UserServiceImpl"></bean> 9 </beans>
第五步,測試spa
1 package com.aaa.spring; 2 import com.aaa.spring.entity.User; 3 import com.aaa.spring.service.UserService; 4 import javafx.application.Application; 5 import org.springframework.context.ApplicationContext; 6 import org.springframework.context.support.ClassPathXmlApplicationContext; 7 /** 8 * 獲取對象 9 */ 10 public class Test01 { 11 public static void main(String[] args) { 12 //建立spring的工廠類對象 13 ApplicationContext context = new ClassPathXmlApplicationContext("applicationContext.xml"); 14 //從工廠中獲取對象 15 UserService userService = context.getBean(UserService.class); 16 userService.saveUser(new User()); 17 userService.deleteUser(new User()); 18 userService.updateUser(new User()); 19 userService.findById(10L); 20 } 21 }
1 package com.aaa.spring.advice; 2 import org.aspectj.lang.JoinPoint; 3 import java.util.Date; 4 /** 5 * 日誌記錄的代碼 6 */ 7 public class LogAdvice { 8 /** 9 * 日誌記錄的代碼,經過JoinPoint對象能夠獲取方法調用的一些參數 10 * @param jp 11 */ 12 public void log(JoinPoint jp){ 13 //獲取調用方法的名稱 14 String methodName = jp.getSignature().getName(); 15 System.out.println(new Date()+"調用了"+methodName); 16 } 17 }
1 <?xml version="1.0" encoding="UTF-8"?> 2 <beans xmlns="http://www.springframework.org/schema/beans" 3 xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" 4 xmlns:context="http://www.springframework.org/schema/context" 5 xmlns:aop="http://www.springframework.org/schema/aop" 6 xsi:schemaLocation="http://www.springframework.org/schema/beans 7 http://www.springframework.org/schema/beans/spring-beans.xsd 8 http://www.springframework.org/schema/context http://www.springframework.org/schema/context/spring context.xsd http://www.springframework.org/schema/aop http://www.springframework.org/schema/aop/spring aop.xsd"> 9 <bean id="userService" class="com.aaa.spring.service.impl.UserServiceImpl"></bean> 10 <!--聲明通知類的對象,蓋了一個傳達室--> 11 <bean id="logAdvice" class="com.aaa.spring.advice.LogAdvice"></bean> 12 <!-- 13 實現aop 至關於實如今有同窗進入學校的時候檢查是否穿了拖鞋 14 --> 15 <aop:config> 16 <!---聲明切入點表達式 expression是什麼要攔截哪些類的哪些方法 17 切入點表達式語法 18 舉例1:若是要攔截全部com.aaa.spring.service.impl包下的UserServiceImpl類的全部以User結尾的方法 19 execution(* com.aaa.spring.service.imp.UserServiceImpl.*User(..)) 20 舉例2:若是要攔截全部類的以User結尾的方法 21 execution(* *User(..)) 22 舉例2:要攔截全部com.aaa.spring包或者子包下全部的以User結尾的方法 23 execution(* com.aaa.spring..*.*User(..)) 24 --> 25 <aop:pointcut id="p1" expression="execution(void *User(..)) "></aop:pointcut> 26 <!---聲明切面,完成日誌記錄的功能--> 27 <aop:aspect ref="logAdvice"> 28 <!--聲明後置通知,在全部攔截的方法執行完以後執行--> 29 <!---攔截到目標方法以後要調用通知類的哪一個方法--> 30 <aop:after-returning method="log" pointcut-ref="p1"></aop:after-returning> 31 </aop:aspect> 32 </aop:config> 33 </beans>
4、測試
通知類型 |
說明 |
註解配置(aop:aspectj-autoproxy) |
aop:before前置通知 |
在目標方法調用以前執行 |
@Before("exception(void *(..))") |
aop:after-returning後置通知 |
在目標方法調用以後執行,一旦目標方法產生異常,不會執行 |
@AfterReturning("execution(*(..))") |
aop:after最終通知 |
在目標方法調用以後執行,不管目標是否產生異常,都會被執行 |
|
aop:after-throwing異常通知 |
在目標方法產生異常的時候執行 |
@AfterThrowing(pointcut="excution(void *(..))",throwing="e") |
aop:arround 環繞通知 |
在目標方法執行以前和 以後都寫一寫非核心的業務邏輯,通常能夠用來替代前置通知和後置通知 |
aop:around,method,pointcut-ref |
aop底層使用了什麼設計模式
使用了動態代理模式 springaop支持jdk動態代理和cglib動態代理
spring aop經常使用的五種通知類型是什麼
前置通知,後置通知,環繞通知,異常通知,最終通知