1. 程式人生 > >Spring快速筆記2

Spring快速筆記2

概述:

  • Spring的概述、SpringIOC入門(XML)、Spring的Bean管理、Spring屬性注入
  • Spring的IOC的註解方式、Spring的AOP開發(XML)
  • Spring的AOP的註解開發、Spring的宣告式事務、JdbcTemplate。
  • SSH的整合、HibernateTemplate的使用、OpenSessionInViewFilter的使用。

 

1. 快速引入遺留問題

在案例中,遺留的一個程式問題是:每次請求都會建立一個Spring的工廠,這樣浪費伺服器資源,應該一個專案只有一個Spring的工廠。在實際開發中,應該遵循:

  • 在伺服器啟動的時候,建立一個Spring的工廠。

  • 建立完工廠,將這個工廠類儲存到ServletContext中。

  • 每次使用的時候都從ServletContext中獲取。

在整合Web專案時的解決方法:引入Spring_web.jar,使用ServletContextListener來監聽ServletContext物件的建立和銷燬,在使用時通過工具類載入工廠applicationContext。也就是通常說的“Spring核心監聽器”。注意:Spring_wab.jar中預設使用的是/WEB-INF/applicationcontext.xml,要手動修改。

 

2. IOC的註解方式

2.1 使用案例

  • IOC註解方式的JAR包:4核心+2日誌,Spring4.x後額外需要一個aop的依賴。

  • xml中引入Context的相關約束:解壓目錄下/docs/spring-framework-reference/html/xsd-configuration.html

  • 示例:

    <beans xmlns="http://www.springframework.org/schema/beans"
    	xmlns:context="http://www.springframework.org/schema/context"
        xmlns:
    xsi="http://www.w3.org/2001/XMLSchema-instance" 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來告知Spring的註解形式 --> <context:component-scan base-package="com.leehao.springlearning.Anno1" /> </beans> -------------------------------------Java--------------------------------------- @Component(value="userDao") public class UserDaoImpl implements UserDao { @Value("HHHH") private String name; // public void setName(String name) { // this.name = name; // } @Override public void save() { System.out.println("Anno1....save:" + name); } }

 

2.2 Component類註解

  • 註解Bean時,使用時必須在xml中配置<context:component-scan>,按名稱注入
    • @符號標識,是一個類;
    • 可以使用註解代替xml配置
    • @component 取代<bean calss=>
    • @component(value=“id”) 取代<bean id=,calss=>,value可以省略
  • Component註解的三個衍生註解,便於開發,後續Spring將逐漸分開支援
    • controller:Web層
    • service:Service層
    • Repository:Dao層
    • 使用與直接使用Component等效

 

2.3 注入屬性的註解

屬性的注入可以直接在屬性的上方,也可以另外生產set方法,對方法進行修飾。

  • 普通值:@Value

  • 物件引用:@Autowired,按屬性型別自動注入,單獨可以使用。一般地,和@Qualifier(value=“”)一同使用

    • 物件引用2:@Resource(name=“”),按照名稱進行注入(Spring引用的其他介面規範的註解),name不可省略。
    @Service("userService")
    public class UserServiceImpl implements UserService {
    //	@Autowired
    //	@Qualifier(value="userDao")  //兩個註解同時使用,按名稱注入,value可以省略
    	@Resource(name="userdao")
    	private UserDao userDao;	
    	@Override
    	public void save() {
    		userDao.save();
    		System.out.println("UserService save...");
    	}
    }
    

 

2.4 Bean的其他註解

  • 生命週期的註解

    • @PostConstruct:初始化註解,相當於<bean>標籤中的init-method
    • @PreDestroy:銷燬註解,相當於<bean>標籤中的destroy-method
  • 類/bean作用範圍註解,後三種不常用

    • @Scope(“prototype”):預設為singleton,單例;

    • 同樣,在多例中Spring無法進行銷燬

    • request

    • session

    • globalsession

 

2.5 XML和註解方式比較

  • 比較

    • XML結構清晰,任何情況下都適用
    • 註解方便,但是隻能對自定義的類進行註解,如一些預設的原始碼或工具類無法配置
  • 混合開發的方式

    • 如XML管理Bean,屬性注入使用註解
    • 注意:使用<context:component-scan>開啟Bean的註解,而若只用屬性注入等註解時,只開啟<context:annotation-config /> 也可。
    <!-- 使用context來告知Spring的註解形式 -->
    <!-- 	<context:component-scan base-package="com.leehao.springlearning" /> -->
    <!-- 可以不開啟掃描,只開啟註釋配置 -->
    <context:annotation-config />
    <bean id="productDao" class="com.leehao.springlearning.Anno2.ProductDao" />
    <bean id="userService" class="com.leehao.springlearning.Anno2.UserServiceImpl"/>
    
  • 1547185993541


3 AOP

面向切面程式設計,底層以代理方式實現;用於事務管理、效能監控、快取、日誌等。

3.1 概念

AOP是OOP的一種延伸,一種新的設計理念。是Spring框架中的一個重要內容,是函數語言程式設計的一種衍生範型。利用AOP可以對業務邏輯的各個部分進行隔離,從而使得業務邏輯各部分之間的耦合度降低,提高程式的可重用性,同時提高了開發的效率。

  • AOP採取橫向抽取機制,取代了傳統縱向繼承體系重複性程式碼
  • 經典應用:事務管理、效能監視、安全檢查、快取、日誌等
  • Spring AOP使用純Java實現,不需要專門的編譯過程和類載入器,執行期通過代理方式向目標類織入增強程式碼
  • AspectJ是一個基於Java語言的AOP框架,Spring2.0開始,Spring AOP引入對Aspect的支援,AspectJ擴充套件了Java語言,提供了一個專門的編譯器,在編譯時提供橫向程式碼的織入

 

3.2 Spring的代理機制

Spring底層使用動態代理的機制,來完成功能的增強;在不改變原始碼基礎上進行拓展增強。

  • JDK 的動態代理:針對實現了介面的類(介面+實現類)產生代理,Spring預設使用的代理機制

  • Cglib 的動態代理 :針對沒有實現介面的類產生代理。應用底層的位元組碼增強的技術,生成當前類的子類物件。類似於Javassist,Hibernate裡使用的——早期版本用的也是cglib。

  • JDK的底層實現——手動示例:

     * 實現InvocationHandler完成自身的代理執行,使用匿名內部類或其他類亦可
    public class JDKProxy implements InvocationHandler {
    	private UserDao userDao;   //通過目標物件的引用,對其進行功能的增強
    	public JDKProxy(UserDao userDao) {
    		this.userDao = userDao;
    	}
    	//生成代理物件
    	public UserDao createProxy() {
    		UserDao userDaoProxy = (UserDao) Proxy.newProxyInstance(
    				userDao.getClass().getClassLoader(), 
    				userDao.getClass().getInterfaces(), 
    				this);
    		return userDaoProxy;
    	}
    	@Override
    	public Object invoke(Object proxy, Method method, Object[] args) throws Throwable {
    		//實現增強,proxy建立例項後的執行方法
    		System.out.println("增強之前....");
    		return method.invoke(userDao, args);   //執行原來的方法
    	}	
    }
    
  • Cglib的底層實現——手動示例:

    spring和核心包已經包含了cglib的包庫。Cglib使用一個Enhancer的核心物件來建立代理物件,但需要說明的是,它採用的是繼承目標物件的方式,一旦目標物件是Final時則無法實現。

    public class CglibPorxy implements MethodInterceptor{
    	private CustomerDao customerDao;
    	public CglibPorxy(CustomerDao customerDao) {
    		this.customerDao = customerDao;
    	}
    	//建立代理
    	public CustomerDao createCustomer() {
    		//1.enhancer核心
    		Enhancer enhancer = new Enhancer();
    		//2.繼承目標類
    		enhancer.setSuperclass(CustomerDao.class);
    		//3.通過回撥生成代理
    		enhancer.setCallback(this);		
    		return (CustomerDao) enhancer.create();
    	}
    	@Override
    	public Object intercept(Object object, Method method, Object[] args, MethodProxy methodProxy) throws Throwable {
    		//執行增強
    		System.out.println("增強...");		
    		return method.invoke(customerDao, args); //methoProxy.invokeSuper(customerDao, args);
    	}	
    }
    

 

3.3 Spring的AOP——基於AspectJ的XML

AOP是一個概念,存在AOP聯盟,而Spring只是較好地運用起來。Spring原始的AOP技術較為複雜,引入了一個AspectJ的框架,來支援Spring的AOP程式設計。

  • AOP相關術語

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

  • JAR包:

    • 基礎Spring的4+2
    • AOP:spring-aop、aspectj、aop聯盟、spring-aspects整合包
  • spring的aop的XML約束:xmlns名稱空間

 

3.4 案例Demo

  • 整合Spring的Junit,使用註解的方式完成工廠的載入,對applicationConetext.xml檔案進行解析,在使用時直接注入需要獲取的bean,方便測試。

    • Jar包:spring-test.xxx.jar

      @RunWith(SpringJUnit4ClassRunner.class)
      @ContextConfiguration("classpath:applicationContext.xml")
      public class AspectJDemo1 {
      	@Resource(name="productDao")
      	private ProductDao productDao;	
      	@Test
      	public void demo1(){
      		productDao.save();
      		productDao.delete();
      		productDao.update();
      	}
      }
      
  • 將需要增強的功能通過切面類來組織,並使用Spring中的xml進行配置。

    <!-- aspectj -->
    <bean id="productDao" class="com.leehao.springlearning.aspectj1.ProductDaoImpl"/>
    <!-- aop的配置 
        1.切面類(增強的封裝):執行的什麼增強
        2.切面:將哪個物件用到了什麼增強,聯絡在一起;執行什麼樣的增強(前,後,異常等)
        3.切入點表示式:在物件的什麼位置執行
    -->
    <bean id="myAspect" class="com.leehao.springlearning.aspectj1.MyAspect"/>
    <aop:config >
        <!-- 切入點表示式 -->
        <aop:pointcut expression="execution(* com.leehao.springlearning.aspectj1.ProductDaoImpl.save(..))" id="pointcut1"/>
        <!-- 切面 -->
        <aop:aspect ref="myAspect">
            <aop:before method="checkPri" pointcut-ref="pointcut1"/>
        </aop:aspect>
    </aop:config>
    
  • Apsect的通知型別:

    • 前置通知:可以使用Jointpoint獲得切入點的相關屬性

      public void checkPri(JoinPoint joinPoint){
          System.out.println("增強..." + joinPoint);
      }
      -------------------------------------------------------------------
      <aop:aspect ref="myAspect">
      	<aop:before method="checkPri" pointcut-ref="pointcut1"/>
      </aop:aspect>
      
    • 後置通知:可以獲得方法的返回值,但xml的配置和方法的通知方法的形參名必須一致

      public void writeLog(Object res) {
      		System.out.println("後置....日誌:" + res);
      	}
      -------------------------------------------------------------------
      <aop:after-returning method="writeLog" pointcut-ref="pointcut2" returning="res"/>
      
    • 環繞通知:前後執行資訊,使用ProceedingJoinPoint型別引數控制切入點的執行(可以阻止)。

      public Object around(ProceedingJoinPoint point) throws Throwable {
      		System.out.println("環繞前..");
      		Object object = point.proceed();
      		System.out.println("環繞後..");
      		return object;		
      	}
      -------------------------------------------------------------------
      <aop:around method="around" pointcut-ref="pointcut3"/>
      
    • 異常丟擲

      public void afterThrow(Throwable tw) {
      		System.out.println(tw.getMessage());
      	}
      -------------------------------------------------------------------
      <aop:after-throwing method="afterThrow" pointcut-ref="pointcut1" throwing="tw"/>
      
    • 最終通知:相當於finally塊

      public void finalReturn() {
      		System.out.println("finallyReturn..");
      	}
      -------------------------------------------------------------------
      <aop:after method="finalReturn" pointcut-ref="pointcut1"/>
      

 

3.5 Aop 的切入點表示式

切入點表示式基於execution函式完成。

表示式:[方法訪問修飾符] 方法返回值 包名.類名.方法名(方法的引數)

  • public * cn.itcast.spring.dao.*.*(…)
  • * cn.itcast.spring.dao.*.*(…) dao下的所有類的所有方法
  • * cn.itcast.spring.dao.UserDao+.*(…)* ——+號表示含其子類
  • * cn.itcast.spring.dao…*.*(…) dao下所有子包的所有類的所有方法

 

 

4 AOP的註解方式

基於AspectJ的註解方式。除了Bean之外的檔案需要在xml檔案中配置外,其他如切面類、切入點(含表示式)、通知型別等都直接在需要增強的地方使用註解來完成。

  • 切面類:@Aspect

  • 通知型別:@Before,@After,@AfterReturning,@Around,@AfterThrowing

  • @Aspect
    public class MyAspectAnno {
    	@Before(value="execution(* com.leehao.springlearning.aop_anno.CustomerDaoImpl.save(..))")
    	public void before(JoinPoint joinPoint) {
    		System.out.println("before..." + joinPoint);
    	}	
    	@AfterReturning(value="execution(* com.leehao.springlearning.aop_anno.CustomerDaoImpl.delete(..))",returning="res")
    	public void afterReturn(Object res) {
    		System.out.println("afterReturn..." + res);
    	}	
    	@Around("execution(* com.leehao.springlearning.aop_anno.CustomerDaoImpl.update(..))")
    	public Object around(ProceedingJoinPoint point) throws Throwable {
    		System.out.println("環繞前..");
    		Object object = point.proceed();
    		System.out.println("around...後");
    		return object;
    	}  
    	@AfterThrowing(value="execution(* com.leehao.springlearning.aop_anno.CustomerDaoImpl.query(..))",throwing="e")
    	public void afterThrow(Throwable e) {
    		System.out.println("afterThrow..."+e.getMessage());
    	}	
    	@After("execution(* com.leehao.springlearning.aop_anno.CustomerDaoImpl.query(..))")
    	public void finalThrow() {
    		System.out.println("finalThrow....");
    	}
    }
    
  • 註解切入點:可以在使用註解時,單獨定義切入點,在需要使用時進行引用即可。可以是作為將執行的切入點表示式抽離出來了。

    //宣告切入點註解
    @Pointcut(value="execution(* com.leehao.springlearning.aop_anno.CustomerDaoImpl.save(..))")
    public void pointCut1(){}
    @Pointcut(value="execution(* com.leehao.springlearning.aop_anno.CustomerDaoImpl.delete(..))")
    public void pointCut2(){}	
    @Pointcut(value="execution(* com.leehao.springlearning.aop_anno.CustomerDaoImpl.update(..))")
    public void pointCut3(){}  //value可省略
    @Pointcut("execution(* com.leehao.springlearning.aop_anno.CustomerDaoImpl.query(..))")
    public void pointCut4(){}
    ----------------------------使用---------------------
    @Before(value="MyAspectAnno.pointCut1()")   //value可省略
    public void before(JoinPoint joinPoint) {
        System.out.println("before..." + joinPoint);
    }
    

 

5 Spring的JDBC

Spring為一站式開發框架,其持久層的支援則是ORM框架,另外一種重要的就是JDBC。Spring提供了許多的模板,簡化了對各個持久層框架的支援,JDBC模板就是其中一種,另外還有如支援Hibernate的、Mybatis的模板。

  • 一個示例:

     * 使用JDBC模板進行建立連線,對資料庫進行操作
     * JDBC模板的使用類似於JDBCUtils
    public void demo1(){
        //1.建立連線池
        DriverManagerDataSource dataSource = new DriverManagerDataSource();
        dataSource.setDriverClassName("com.mysql.jdbc.Driver");
        dataSource.setUrl("jdbc:mysql://localhost:3306/springlearning");
        dataSource.setUsername("root");
        dataSource.setPassword("123456");
        //2.建立JDBC模板,需要連線池
        JdbcTemplate jdbcTemplate = new JdbcTemplate(dataSource);
        jdbcTemplate.update("insert into user values(null, ?, ?)", "王五", 2000d);
    }
    

 

5.1 JDBC的模板使用

使用Spring的註解方式,將JDBC模板及其依賴的資料來源,都交給Spring去完成,在配置檔案中配置相應的Bean。注意:Spring4之後,使用時需要引入AOP的jar包。

@RunWith(SpringJUnit4ClassRunner.class)
@ContextConfiguration("classpath:applicationContext.xml")
public class JdbcDemo2 {
	@Resource(name="jdbcTemplate")
	private JdbcTemplate jdbcTemplate;
	@Test
	public void demo1() {
		jdbcTemplate.update("insert into user values(null, ?, ?)", "zhaoliu", 2000d);
	}
}
-----------------------------------------------------------
<!-- 配置資料驅動源 -->
<bean id
            
           

相關推薦

Spring快速筆記2

概述: Spring的概述、SpringIOC入門(XML)、Spring的Bean管理、Spring屬性注入 Spring的IOC的註解方式、Spring的AOP開發(XML) Spring的AOP的註解開發、Spring的宣告式事務、JdbcT

Spring MVC 筆記2 HelloWorld

實現這個例子的問題 WEB-INFO目錄下必須有spring的包,放在lib下;如下圖(這裡我直接把idea建立時宣稱springmvc,然後把idea給的lib拷貝了下來,也可以的) request mapping中的可以不寫value則預設 在HTML中標題後面跟數字可以控制字型大小,在段

Spring學習筆記2Spring專案 環境搭建

作者:藝術就是爆炸  出處:https://blog.csdn.net/lianjiww/article/details/53571795 準備好相應的環境: 我們需要如下內容:  - eclipse,這裡我選用的是Eclipse Java EE IDE for Web

Spring學習筆記-2:JSP標準標籤庫

個人部落格站已經上線了,網址 www.llwjy.com ~歡迎各位吐槽~-------------------------------------------------------------------------------------------------   

Spring快速筆記3

概述: Spring的概述、SpringIOC入門(XML)、Spring的Bean管理、Spring屬性注入 Spring的IOC的註解方式、Spring的AOP開發(XML) Spring的AOP的註解開發、Spring的宣告式事務、JdbcT

Spring快速筆記1

概述: Spring的概述、SpringIOC入門(XML)、Spring的Bean管理、Spring屬性注入 Spring的IOC的註解方式、Spring的AOP開發(XML) Spring的AOP的註解開發、Spring的宣告式事務、

Struts2 快速筆記2

路線: Struts2的概述、Struts2的入門、Struts2常見的配置、Struts2的Action的編寫 Struts2的資料的封裝、結果頁面配置 Struts2的值棧和OGNL表示式 Struts2的標籤庫 上一

Hibernate快速筆記2

上篇:Hibernate快速筆記1 1.Hibernate的查詢方式 2.Hibernate的抓取策略 Hibernate查詢方式 OID檢索:根據ID查詢物件,Get/Load方法 session.get(Customer.class,1L) ses

spring學習筆記2——IOC

一、IOC概述ioc:控制反轉。控制:當前物件對內部成員的控制權。反轉:這種控制權不由當前物件管理了,由其他(類,容器)來管理。ioc的好處:1、不用自己組裝,拿來就用2、享受單例好處,效率高,不佔空間3、統一配置,便與修改二、IOC原理ioc其實就是一個大工廠,用來管理所有

Spring學習筆記2

SpringIOC IOC 依賴注入:DI IOC的好處 IOC的通俗理解 一.IOC(Inversion of Control,控制反轉)是sping的核心,貫穿始終。 所謂IOC,

spring筆記2-註解

pooled ace val autowired [] xmlns quest repo 數據庫 一.屬性與成員變量的區別: 屬性:對外暴露的,getxxx/setxxx稱為屬性; 成員變量:private String name稱為成員變量或字段 二.applicati

(來換項目系列)Spring學習筆記2

servlet span on() 購物車 集成 因此 proxy center str 3.1.1 配置profile bean 使用@profile 註解 例如 @Configuration @Profile("dev") public class xxxConfig{

spring (4.0.2)——(尚矽谷)學習筆記1

aspect 什麽 企業應用 周期 持久層 非侵入 mvc 註入 JD 1、Spring是什麽?   ①Spring 是一個開源框架;   ②Spring 為簡化企業級應用開發而生。使用Spring可以使簡單的JavaBean實現以前只有EJB才能實現的功能。   ③Spr

spring筆記(2)spring的3種IOC容器配置方式

enc get utf-8 xmla height frame lan system () 1.通過 @Configuration 和 @bean 實現 @Configurationpublic class Ch2BeanConfiguration { @Bean

Spring基礎:快速入門spring boot(2):SPRING INITIALIZR

分享一下我老師大神的人工智慧教程!零基礎,通俗易懂!http://blog.csdn.net/jiangjunshow 也歡迎大家轉載本篇文章。分享知識,造福人民,實現我們中華民族偉大復興!        

Spring基礎:快速入門spring cloud(2):服務發現之eureka

分享一下我老師大神的人工智慧教程!零基礎,通俗易懂!http://blog.csdn.net/jiangjunshow 也歡迎大家轉載本篇文章。分享知識,造福人民,實現我們中華民族偉大復興!        

Spring基礎 快速入門spring boot(2SPRING INITIALIZR

我們 com core key code amp control 項目 files SPRING INITIALIZR是spring boot在構建項目時候非常有效, 雖然說Maven以及Spring boot提供的starter使用起來非常簡單, 但是由於組件和關聯部

2.Spring學習筆記之 ————IoC(控制反轉)

控制反轉(IoC),是Spring裡一個專有的名詞,其意思就是說,物件的例項由Spring容器來進行建立而不是我們自己手動建立,當我們在Spring容器中設定好Bean屬性後,Spring容器就會自動建立其例項,我們只要去呼叫Spring的Bean就行。 接下來是例子:

Spring boot學習筆記2--pom.xml初探究

新建的springboot_study專案的pom.xml結構如下: <parent> <groupId>org.springframework.boot</groupId> <artifactId&g

Spring Boot學習筆記2——基本使用之最佳實踐[z]

前言 在上一篇文章Spring Boot 學習筆記1——初體驗之3分鐘啟動你的Web應用已經對Spring Boot的基本體系與基本使用進行了學習,本文主要目的是更加進一步的來說明對於Spring Boot使用上的具體的細節以及使用上的最佳實踐, 經過了幾天的文件閱讀和實驗,將自己這幾天的學習心得在