Spring的IOC註解開發與AOP

一 IOC實現的註解形式

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、註解屬性注入

二 AOP的開發

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("最終通知執行了"); } }
View Code

   (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>
View Code

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

相關文章
相關標籤/搜索