1. 程式人生 > >spring註解開發及AOP

spring註解開發及AOP

Spring的bean管理(註解)

  註解介紹

    1 程式碼裡面特殊標記,使用註解可以完成功能

 

    2 註解寫法 @註解名稱(屬性名稱=屬性值)

 

    3 註解使用在類上面,方法上面 和 屬性上面

 

  Spring註解開發準備

    1 匯入jar包

      (1)匯入基本的jar包

        

      (2)匯入aop的jar包

        

    2 建立類,建立方法

 

    3 建立spring配置檔案,引入約束

    (1)第一天做ioc基本功能,引入約束beans

    (2)做spring的ioc註解開發,引入新的約束

<beans xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
       xmlns:context="http://www.springframework.org/schema/context"
       xmlns:aop="http://www.springframework.org/schema/aop"
       xmlns="http://www.springframework.org/schema/beans"
       xsi:schemaLocation="http://www.springframework.org/schema/beans
        http://www.springframework.org/schema/beans/spring-beans.xsd
        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"
>

    4 開啟註解掃描:一般使用上面的掃描方式

    <!-- 開啟註解掃描 
        (1)到包裡面掃描類、方法、屬性上面是否有註解
    -->
    <context:component-scan base-package="cn.itcast"></context:component-scan>
    
    <!-- 
        掃描屬性上面的註解
     -->
    <!-- <context:annotation-config></context:annotation-config> 
-->

 

  註解建立物件

    1 在建立物件的類上面使用註解實現

@Component(value="user")
public class User {

    public void add() {
        System.out.println("User......");
    }
}
public class TestAnno {

    @Test
    void testName() throws Exception {
        ApplicationContext context = 
                new ClassPathXmlApplicationContext("bean1.xml");
        User user = (User) context.getBean("user");
        user.add();
    }
}

    

    2 建立物件有四個註解

        

    (1)@Component

    (2)@Controller

    (3)@Service

    (4)@Repository

      目前這四個註解功能是一樣的,都建立物件

 

    3 建立物件單例項還是多例項

@Service(value="user")
@Scope(value="prototype")
public class User {

    public void add() {
        System.out.println("User......");
    }
}

 

  註解注入屬性

    1 建立service類,建立dao類,在service得到dao物件

      注入屬性第一個註解 @Autowired

      (1)建立dao和service物件

@Component(value="userDao")
public class UserDao {

    public void add() {
        System.out.println("dao.........");
    }
}
@Service(value="userService")
public class UserService {

    //得到dao物件
    //1 定義dao型別屬性
    //在dao屬性上面使用註解 完成物件注入
    @Autowired
    private UserDao userDao;
    // 使用註解方式時候不需要set方法
    
    public void add() {
        System.out.println("service...........");
        userDao.add();
    }
}

 

      注入屬性第二個註解 @Resource

@Service(value="userService")
public class UserService {

    // name屬性值 寫 註解建立dao物件 value值
    @Resource(name="userDao")
    private UserDao userDao;
    
    public void add() {
        System.out.println("service...........");
        userDao.add();
    }
}

 

 

配置檔案和註解混合使用

  1 建立物件操作使用配置檔案方式實現

    <!-- 配置物件 -->
    <bean id="bookService" class="cn.itcast.xmlanno.BookService"></bean>
    <bean id="bookDao" class="cn.itcast.xmlanno.BookDao"></bean>
    <bean id="ordersDao" class="cn.itcast.xmlanno.OrdersDao"></bean>

  2 注入屬性的操作使用註解方式實現

    //得到bookdao和ordersdao物件
    @Resource(name="bookDao")
    private BookDao bookDao;
    
    @Resource(name="ordersDao")
    private OrdersDao ordersDao;

 

 

AOP概念

  1 aop:面向切面(方面)程式設計,擴充套件功能不修改原始碼實現

 

  2  AOP採取橫向抽取機制,取代了傳統縱向繼承體系重複性程式碼

 

  3 aop底層使用動態代理實現

    (1)第一種情況,有介面情況,使用動態代理建立介面實現類代理物件

    (2)第二種情況,沒有介面情況,使用動態代理建立類的子類代理物件

 

AOP原理

  畫圖分析原理

 

AOP操作術語

  Joinpoint(連線點): 類裡面可以被增強的方法,這些方法稱為連線點

 

  Pointcut(切入點):所謂切入點是指我們要對哪些Joinpoint進行攔截的定義.

 

  Advice(通知/增強):所謂通知是指攔截到Joinpoint之後所要做的事情就是通知.通知分為前置通知,後置通知,異常通知,最終通知,環繞通知(切面要完成的功能)

 

  Aspect(切面): 是切入點和通知(引介)的結合

 

  Introduction(引介):引介是一種特殊的通知在不修改類程式碼的前提下, Introduction可以在執行期為類動態地新增一些方法或Field.

  Target(目標物件):代理的目標物件(要增強的類)

  Weaving(織入):是把增強應用到目標的過程.

            把advice 應用到 target的過程

  Proxy(代理):一個類被AOP織入增強後,就產生一個結果代理類

 

Spring的aop操作

    1 在spring裡面進行aop操作,使用aspectj實現

    (1)aspectj不是spring一部分,和spring一起使用進行aop操作

    (2)Spring2.0以後新增了對AspectJ支援

 

    2 使用aspectj實現aop有兩種方式

    (1)基於aspectj的xml配置

    (2)基於aspectj的註解方式

 

  Aop操作準備

    1 除了匯入基本的jar包之外,還需要匯入aop相關的jar包

      

    2 建立spring核心配置檔案,匯入aop的約束

 

  使用表示式配置切入點

    1 切入點:實際增強的方法

 

    2 常用的表示式

      execution(<訪問修飾符>?<返回型別><方法名>(<引數>)<異常>)

      (1)execution(* cn.itcast.aop.Book.add(..))

      (2)execution(* cn.itcast.aop.Book.*(..))

      (3)execution(* *.*(..))

      (4) 匹配所有save開頭的方法 execution(* save*(..))

 

  Aspectj的aop操作

    <!-- 1  配置物件 -->
    <bean id="book" class="cn.itcast.aop.Book"></bean>
    <bean id="myBook" class="cn.itcast.aop.MyBook"></bean>
    
    <!-- 2 配置aop操作 -->
    <aop:config>
        <!-- 2.1 配置切入點 -->
        <aop:pointcut expression="execution(* cn.itcast.aop.Book.*(..))" id="pointcut1"/>
        
        <!-- 2.2 配置切面 
            把增強用到方法上面
        -->
        <aop:aspect ref="myBook">
            <!-- 配置增強型別 
                method: 增強類裡面使用哪個方法作為前置
            -->
            <aop:before method="before1" pointcut-ref="pointcut1"/>
            
            <aop:after-returning method="after1" pointcut-ref="pointcut1"/>
            
            <aop:around method="around1" pointcut-ref="pointcut1"/>
        </aop:aspect>
    </aop:config>
public class MyBook {

    public void before1() {
        System.out.println("前置增強......");
    }
    
    public void after1() {
        System.out.println("後置增強......");
    }
    
    //環繞通知
    public void around1(ProceedingJoinPoint proceedingJoinPoint) throws Throwable {
        //方法之前
        System.out.println("方法之前.....");
        
        //執行被增強的方法
        proceedingJoinPoint.proceed();
        
        //方法之後
        System.out.println("方法之後.....");
    }
}