Spring4_Day02

Spring4_Day01

Spring的IOC註解開發(重點)

入門案例

  1. 創建一個web項目
  2. 引入相應的包

在這裏插入圖片描述
3. 創建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:context="http://www.springframework.org/schema/context" 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">
</beans>
  1. 編寫相關的類
package com.lld.Dao.Impl;

import org.springframework.beans.factory.annotation.Value;
import org.springframework.stereotype.Component;

import com.lld.Dao.UserDao;

@Component("UserDao")//這一句話相當於<bean id="UserDao" class="com.lld.Dao.Impl.UserDaoImpl" />
public class UserDaoImpl implements UserDao {

	@Value("曲光光")//類似於將值注入到name中
	private String name;
	
	@Override
	public void save() {
		System.out.println("UserDao執行成功......"+name);
	}

}
  1. 在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:context="http://www.springframework.org/schema/context" 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">
		<context:component-scan base-package="com.lld"/><!-- 該段說明com.lld包下面的都使用註解的方法執行 -->	
</beans>
  1. 編寫測試類
@Test
	/*
	 * 註解方式
	 */
	public void demo02(){
		ApplicationContext applicationContext = new ClassPathXmlApplicationContext("applicationContext.xml");
		
		UserDao userDao = (UserDao) applicationContext.getBean("UserDao");
		
		userDao.save();
	}
  1. 運行結果
    在這裏插入圖片描述

Spring的IOC註解詳解

@Component:組件(作用在類上)

  • @Controller :WEB 層
  • @Service : 業務層
  • @Repository : 持久層

屬性注入的註解:(使用註解注入的方式,可以不提供set方法)

  • @Value() :用於注入普通類型
  • @Autowired():自動裝配

1.默認按照類型進行匹配
2.按照名稱注入
@Qualifier :強制使用名稱注入

  • @Resource(name=" ")相當於

@Autowired和@Qualifier(" ")一起使用

生命週期注入

  • @PostConstruct :創建時調用
  • @PreDestroy :銷燬時調用

作用範圍註解

  • @scope("")

      1. singleton				:單例
      2. prototype				:多例
      3. request				:創建後存入request域中
      4. session				:創建後存入session域中
      5. globalsession			:應用在web項目中,必須在porlet環境下使用。但是如果沒有這種環境,相對於session。
    

IOC的XML和註解開發比較

XML和註解的比較

  • 適用場景

xml:任何場景(結構清晰,方便維護)
註解:有些地方用不了,在這個類不是自己編寫的時候,註解無法往源代碼上加(開發方便)

XML和註解整合開發

  • XML管理Bean,註解完成屬性注入
  • 在使用註解和xml整合開發時將<context:component-scan base-package=“com.lld”/>換成<context:annotation-config />
<!-- <context:component-scan base-package="com.lld"/>該段說明com.lld包下面的都使用註解的方法執行 -->
		<context:annotation-config /><!--在只使用註解進行屬性注入時,使用該標籤-->

AOP概述(面向切面編程)

什麼是AOP

在這裏插入圖片描述

爲什麼學習AOP

對程序進行增強:在不修改源碼的情況下

  • AOP可以進行權限校驗,日誌記錄,性能監控,事務控制

SpringAOP的由來

AOP 最早由 AOP 聯盟的組織提出的,制定了一套規範.Spring 將 AOP 思想引入到框架中,必須遵守 AOP 聯盟的規範

底層實現

代理機制:

  • Spring 的 AOP 的底層用到兩種代理機制:
    • JDK 的動態代理 :針對實現了接口的類產生代理.
    • Cglib 的動態代理 :針對沒有實現接口的類產生代理. 應用的是底層的字節碼增強的技術 生成當前類的子類對象.

Spring的基於Aspectj的開發

AOP開發中的相關術語及解釋

在這裏插入圖片描述

* joinpoint(連接點):所謂連接點是指那些被攔截到的點。在 spring 中,這些點指的是方法,因爲 spring 只支持方法類型的連接點.
* Pointcut(切入點):所謂切入點是指我們要對哪些 Joinpoint 進行攔截的定義.
* Advice(通知/增強):所謂通知是指攔截到 Joinpoint 之後所要做的事情就是通知.通知分爲前置通知,後置通知,異常通知,最終通知,環繞通知(切面要完成的功能)
* Introduction(引介):引介是一種特殊的通知在不修改類代碼的前提下, Introduction 可以在運行期爲類動態地添加一些方法或 Field.
* Target(目標對象):代理的目標對象
* Weaving(織入):是指把增強應用到目標對象來創建新的代理對象的過程.spring 採用動態代理織入,而 AspectJ 採用編譯期織入和類裝在期織入
* Proxy(代理):一個類被 AOP 織入增強後,就產生一個結果代理類
* Aspect(切面): 是切入點和通知(引介)的結合

入門練習

1. 創建web項目引入jar包

在這裏插入圖片描述

2.編寫目標類(被增強的類)
  • 接口
package demo2;

public interface ProductDao {
	public void save();
	public void update();
	public void delete();
	public void find();
}
  • 實現類
package demo2;

public class ProductDaoImpl implements ProductDao {

	@Override
	public void save() {
		System.out.println("商品保存...");
	}

	@Override
	public void update() {
		System.out.println("商品更新...");
	}

	@Override
	public void delete() {
		System.out.println("商品刪除...");
	}

	@Override
	public void find() {
		System.out.println("尋找商品...");
	}

}
3.編寫增強類
package demo2;

public class MyAspectXml {
	
	public void before(){
		System.out.println("進行權限校驗...............");
	}
}

4.添加配置文件(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"> <!-- bean definitions here -->

	<!-- 把目標類交給spring管理 -->
	<bean id="ProductDao" class="demo2.ProductDaoImpl" />
	
	<!-- 將切面類交給spring管理 -->
	<bean id="MyAspectXml" class="demo2.MyAspectXml" />
	
	<!-- 進行AOP配置 -->
	<aop:config>
	
		<!-- 配置被增強的方法 -->
		<aop:pointcut expression="execution(* demo2.ProductDao.save(..))" id="pointcut1"/>
		
		<!-- 
			1. 配置增強的方法
				* ref:增強的類的id
		 -->
		<aop:aspect ref="MyAspectXml">
			<!-- 
				* method:使用增強類的那一個方法增強 
				* pointcut-ref:被增強的方法
			-->
			<aop:before method="before" pointcut-ref="pointcut1"/>
		</aop:aspect>
	
	</aop:config>

</beans>
5.整合Junite測試
  • 導入jar包

spring-test-4.2.4.RELEASE.jar

  • 添加註解

@RunWith(SpringJUnit4ClassRunner.class) #固定格式
@ContextConfiguration(“classpath:applicationContext.xml”) #classpath後面寫要讀取得配置文件

  • 測試代碼
package demo2;

import javax.annotation.Resource;

import org.junit.Test;
import org.junit.runner.RunWith;
import org.springframework.test.context.ContextConfiguration;
import org.springframework.test.context.junit4.SpringJUnit4ClassRunner;


@RunWith(SpringJUnit4ClassRunner.class)						//固定格式
@ContextConfiguration("classpath:applicationContext.xml")	//classpath後填寫要讀取得配置文件
public class demo2 {
	@Resource(name="ProductDao")							//使用屬性注入
	private ProductDao ProductDao;
	@Test
	public void demo01(){
		ProductDao.save();
		ProductDao.delete();
		ProductDao.find();
		ProductDao.update();
		
	}
}

Spring通知解釋

1. 前置通知:在目標方法執行前進行操作
  • 前置通知:獲得切入點信息
2. 後置通知:在目標方法執行後操作
  • 後置通知:獲得方法值
3. 環繞通知:在目標方法執行前和執行後操作
  • 環繞通知:
4. 異常拋出通知:在程序出現異常時進行操作
5. 最終通知:無論代碼是否有異常,總是會執行
6. 引介通知(不會用)
  • 增強類代碼
package demo2;

import org.aspectj.lang.JoinPoint;
import org.aspectj.lang.ProceedingJoinPoint;

public class MyAspectXml {
	
	/**
	 * 前置通知
	 * @param joinPoint
	 */
	public void before(JoinPoint joinPoint){
		System.out.println("進行權限校驗..............."+joinPoint);
	}
	
	/**
	 * 後置通知
	 * @param result
	 */
	public void writeLog(Object result){
		System.out.println("進行日誌記錄................."+result);
	}
	
	/**
	 * 環繞通知
	 * @param joinPoint
	 * @return
	 * @throws Throwable
	 */
	public Object around(ProceedingJoinPoint joinPoint)throws Throwable{
		
		System.out.println("環繞前通知......");
		Object object = joinPoint.proceed();
		System.out.println("環繞後通知......");
		
		return object;
	}
	
	/**
	 * 異常通知
	 * @param ex
	 */
	public void afterThrowing(Throwable ex){
		System.out.println("異常拋出通知"+ex.getMessage());
	}
	
	public void after(){
		System.out.println("最終通知");
	}
}
  • 被增強類代碼
package demo2;

public class ProductDaoImpl implements ProductDao {

	@Override
	public void save() {
		System.out.println("商品保存...");
	}

	@Override
	public void update() {
		System.out.println("商品更新...");
	}

	@Override
	public String delete() {
		System.out.println("商品刪除...");
		return "曲禿";
	}

	@Override
	public void find() {
		System.out.println("尋找商品...");
	}

}

  • 配置文件
<?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 -->

	<!-- 把目標類交給spring管理 -->
	<bean id="ProductDao" class="demo2.ProductDaoImpl" />
	
	<!-- 將切面類交給spring管理 -->
	<bean id="MyAspectXml" class="demo2.MyAspectXml" />
	
	<!-- 進行AOP配置 -->
	<aop:config>
	
		<!-- 配置被增強的方法 -->
		<aop:pointcut expression="execution(* demo2.ProductDao.save(..))" id="pointcut1"/>
		<aop:pointcut expression="execution(* demo2.ProductDao.delete(..))" id="pointcut2"/>
		<aop:pointcut expression="execution(* demo2.ProductDao.update(..))" id="pointcut3"/>
		<aop:pointcut expression="execution(* demo2.ProductDao.find(..))" id="pointcut4"/>
		
		<!-- 
			1. 配置增強的方法
				* ref:增強的類的id
		 -->
		<aop:aspect ref="MyAspectXml">
			<!-- 
				* aop:before:前置通知
				* method:使用增強類的那一個方法增強 
				* pointcut-ref:被增強的方法
			-->
			<aop:before method="before" pointcut-ref="pointcut1"/>
			<!-- aop:after-returning:後置通知 -->
			<aop:after-returning method="writeLog" pointcut-ref="pointcut2" returning="result"/>
			<!-- aop:around:環繞通知 -->
			<aop:around method="around" pointcut-ref="pointcut3"/>
			<!-- aop:after-throwing:異常拋出通知 -->
			<aop:after-throwing method="afterThrowing" pointcut-ref="pointcut4" throwing="ex"/>
			<!-- aop:after -->
			<aop:after method="after" pointcut-ref="pointcut4"/>
			
		</aop:aspect>
	
	</aop:config>

</beans>

切面表達式

execution(表達式)
表達式:
[方法訪問修飾符] 方法返回值 包名.類名.方法名(方法的參數)
public * cn.itcast.spring.dao.*.*(..)
* cn.itcast.spring.dao.*.*(..)
* cn.itcast.spring.dao.UserDao+.*(..)
* cn.itcast.spring.dao..*.*(..)
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章