1SpringAOP的經常使用註解html
官方建議使用這三個衍生註解,層次清晰,針對每一層
@Controller web層
@Service service層
@Responsitory dao層java
@Autowired 注入對象,按類型注入。咱們通常都是按照名稱來注入,加一個Qualifier註解,必須讓@Autowired和@Qualifier一塊兒來使用,來完成按照名稱的屬性注入,
通常屬性用value,對象屬性用Resource
代碼實現:web
(1)編寫UserDao的接口spring
package com.itheima.demo1; public interface UserDao { public void save(); }
(2)ApplicationContext.xml配置express
(3)編寫UserDao的實現類編程
package com.itheima.demo1; import org.springframework.beans.factory.annotation.Value; import org.springframework.stereotype.Repository; //標記數據訪問組件,即UserDao @Repository("UserDao") public class UserDaoImpl implements UserDao { @Value("花花") private String name; @Override public void save() { System.out.println("UseDao的save方法執行了"+" 姓名是"+name); } }
(4)測試類app
public class TestDemo1 { /** * 使用註解的方式實現 * demo1使用的是UserDao */ @Test public void demo1(){ ApplicationContext applicationContext=new ClassPathXmlApplicationContext("applicationContext.xml"); UserDao userDao= (UserDao) applicationContext.getBean("UserDao"); userDao.save(); } }
運行成功的結果圖:框架
2 Bean做用的做用範圍的註解(重點):ide
@scope
singleton:單例
prototype:多例oop
3 Bean的聲明週期的註解
初始化的註解:PostCostrucct
銷燬的註解:PerDestroy
代碼片斷
4XML和註解的比較
XML:適合任何場景 特色:結構清晰,方便維護
註解:有些地方用不了(這個類不是本身提供的) 特色:開發方便
XML和註解整合開發(各取所長),XML管理Bean、註解屬性注入
1 什麼是AOP?
AOP爲Aspect Oriented Programming的縮寫,意爲:面向切面編程。AOP是OOP的擴展、延申,解決oop開發遇到的問題。
利用AOP能夠對業務邏輯的各個部分進行隔離,從而使得業務邏輯各部分之間的耦合度下降,提升程序的可重用性,同時提升了開發的效率。
2 AOP採用的是橫向抽取機制(代理機制)取代了傳統的縱向繼承.
Spring底層的AOP實現原理是動態代理
jdk的動態代理:只能對實現接口的類實現動態代理
Cglib動態代理(相似於Javassist第三方的動態代理)
3 jdk的動態代理部分代碼實現
jdkProxy類
package com.baidu.demo; import java.lang.reflect.InvocationHandler; import java.lang.reflect.Method; import java.lang.reflect.Proxy; public class JdkProxy implements InvocationHandler { private UserService userService; //把加強的對象傳到proxy中 public JdkProxy(UserService userService) { this.userService=userService; } public UserService createProxy(){ UserService Userproxy=(UserService) Proxy.newProxyInstance(userService.getClass().getClassLoader(), userService.getClass().getInterfaces(), this);//當時這裏寫錯了 return Userproxy; } @Override public Object invoke(Object proxy, Method method, Object[] args) throws Throwable { //若是是save方法,那麼就增強 if("save".equals(method.getName())){ System.out.println("權限校驗成功了............."); return method.invoke(userService,args); } return method.invoke(userService,args); } }
4 Cglib動態代理的部分代碼實現
package com.baidu.demo2; import org.springframework.cglib.proxy.Enhancer; import org.springframework.cglib.proxy.MethodInterceptor; import org.springframework.cglib.proxy.MethodProxy; import java.lang.reflect.Method; public class CglibProxy implements MethodInterceptor { //把要加強的類傳進來 CustomerDao customerDao=new CustomerDao(); public CglibProxy(CustomerDao customerDao) { this.customerDao = customerDao; } public CustomerDao createProxy(){ Enhancer enhancer=new Enhancer(); //設置父類 enhancer.setSuperclass(customerDao.getClass()); //設置回調 enhancer.setCallback(this); CustomerDao customerDao = (CustomerDao) enhancer.create(); return customerDao; } @Override public Object intercept(Object proxy, Method method, Object[] args, MethodProxy methodProxy) throws Throwable { //判斷方法是否爲空 if("save".equals(method.getName())){ //加強 System.out.println("權限校驗成功啦....."); return methodProxy.invokeSuper(proxy,args); } return methodProxy.invokeSuper(proxy,args); } }
5 Spring AOP的開發(基於Aspect J的XML方式)
你要想進行AOP的開發,就必須得了解一些相關的術語
Joinpoint:只要被攔截的點就成爲鏈接點
Pointcut:切入點,真正被攔截到的點
Advice:通知、加強 加強的方法稱爲是通知,在方法執行以前,稱爲前置通知。日誌記錄、性能監控稱爲是後置通知
Introduction:引介。類層面的加強
Target:被加強的對象
Weaving:織入。通知應用(action)到目標Target的過程
Proxy:織入以後產生了一個代理對象
Aspect:切面多個通知和多個切入點的組合
6 Spring AOP的XML開發
通知類型(前三個是咱們用的比較多的)
1前置通知 得到切入點的信息
2後置通知 得到返回值的類型,afterreturning
3環繞通知(功能最強的一個通知) proceed
4異常拋出通知 用於拋出異常的
5最終通知
不管有沒有異常,最終通知總會執行的
(1)Aspect類
package com.baidu.demo3; import org.aspectj.lang.JoinPoint; import org.aspectj.lang.ProceedingJoinPoint; /** * 這是一個切面類 */ public class aspetctJXMl { /** * 前置通知 * @param joinPoint */ //加強權限校驗,提供加強的方法 public void checkPri(JoinPoint joinPoint) { System.out.println("權限已經校驗啦....." + joinPoint); } /** * 後置通知 * @param result * @return */ public String log(Object result){ System.out.println("日誌已經記錄下來了....."+result); return "aa"; } /** * 環繞通知,功能最強的一個 * @param proceedingJoinPoint * @return */ public Object around(ProceedingJoinPoint proceedingJoinPoint) throws Throwable { System.out.println("環繞以前......."); Object proceed = proceedingJoinPoint.proceed(); System.out.println("環繞以後......."); return proceed; } /** * 異常拋出通知 */ public void afterThrowable(Throwable th){ System.out.println("異常拋出通知執行了....."+th); } /** * 最終通知 */ public void Final(){ System.out.println("最終通知執行了"); } }
(2)在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"> <!-- bean definitions here --> <bean id="productDao" class="com.baidu.demo3.ProductDaoImpl"/> <!--將切面類交給spring管理--> <bean id="aspect" class="com.baidu.demo3.aspetctJXMl"/> <!--AOP的配置--> <aop:config> <aop:pointcut id="product1" expression="execution(* com.baidu.demo3.ProductDaoImpl.save(..))"/> <aop:pointcut id="product2" expression="execution(* com.baidu.demo3.ProductDaoImpl.delete(..))"/> <aop:pointcut id="product3" expression="execution(* com.baidu.demo3.ProductDaoImpl.update(..))"/> <aop:pointcut id="product4" expression="execution(* com.baidu.demo3.ProductDaoImpl.find(..))"/> <!--配置切面--> <aop:aspect ref="aspect"> <!--前置通知--> <aop:before method="checkPri" pointcut-ref="product1"/> <!--後置通知--> <aop:after-returning method="log" pointcut-ref="product2" returning="result"/> <!--環繞通知--> <aop:around method="around" pointcut-ref="product3" /> <!--異常拋出通知--> <aop:after-throwing method="afterThrowable" pointcut-ref="product4" throwing="th"/> <!--最終通知--> <aop:after method="Final" pointcut-ref="product4"/> </aop:aspect> </aop:config> </beans>
7 SPring AOP的註解開發
(1)Aspect類
package com.baidu.demo4; import org.aspectj.lang.annotation.*; import org.springframework.stereotype.Component; @Component //組件 @Aspect //切面多個通知和多個切入點的組合 public class aspect { //聲明一個公共的切入點 @Pointcut("execution(* com.baidu.demo4.UserService.*(..))") //任意返回值 任意方法 任意參數 public void myPointCut() { } //加強的方法 @Before("myPointCut()") public void log() { System.out.println("日誌記錄成功啦==============="); } @After("myPointCut()") public void save() { System.out.println("性能檢測成功啦============="); } @AfterThrowing("myPointCut()") public void b() { System.out.println("檢測出來了異常==============="); } }
(2)zhujie.xml
(3)測試類
@RunWith(SpringJUnit4ClassRunner.class) @ContextConfiguration("classpath:zhujie.xml") public class SpringTest2 { @Resource private UserService userService; @Test public void demo(){ userService.find(); userService.save(); userService.delete(); } }
最後,附上一節的Spring框架的快速入門 http://www.javashuo.com/article/p-tolibzyw-be.html
英文單詞:Component:組件
原文出處:https://www.cnblogs.com/bao6/p/10403049.html