Spring-構造注入&註解注入&代理模式&AOP

1.   課程介紹

  • 1.  依賴注入;(掌握)
  • 2.  XML自動注入;(掌握)
  • 3.  全註解配置;(掌握)
  • 4.  代理模式;(掌握)
  • 5.  AOP;(掌握)
  1. 依賴注入;(掌握)

2.1.  構造參數注入java

本身用得很少,除非是其餘框架提供的類可能會用到mysql

經常使用的是方案1、二spring

2.1.1.   方案一:根據構造器參數的順序(索引)sql

<!-- 按照索引注入,索引開始爲0 -->編程

<bean id="MyBean" class="cn.itsource._01_.MyBean">數組

         <constructor-arg index="0" value="666" />框架

         <constructor-arg index="1" value="張二娃" />學習

</bean>測試

2.1.2.   方案二:根據構造器參數的名稱prototype

<!-- 按照名稱注入,名稱必須一致,相似set注入相似 -->

<bean id="MyBean" class="cn.itsource._01_.MyBean">

         <constructor-arg name="id" value="1" />

         <constructor-arg name="name" value="張三娃" />

</bean>

2.1.3.   方案三:根據構造器的類型注入

<!-- 按照類型注入,必須一一對應,不能有重複的類型-->

<bean id="MyBean" class="cn.itsource._01_.MyBean">

         <constructor-arg type="java.lang.Long" value="1" />

         <constructor-arg type="java.lang.String" value="張四娃" />

</bean>

2.2.  若是有一個參數是咱們本身的一個對象,怎麼解決?

2.2.1.   方案一:先在外面定義好

<bean id="otherBean" class="cn.itsource._01_.OtherBean"/>

<bean id="MyBean" class="cn.itsource._01_.MyBean">

         <constructor-arg  value="1" />

         <constructor-arg  value="張五娃" />

         <constructor-arg ref="otherBean"/>

</bean>

2.2.2.   方案二: 使用一個內部的Bean完成(不須要加id)

<bean id="MyBean" class="cn.itsource._01_.MyBean">

         <constructor-arg  value="1" />

         <constructor-arg  value="張六娃" />

         <constructor-arg>

                  <bean class="cn.itsource._01_.OtherBean"/>

         </constructor-arg>

</bean>

2.3.  其它簡單、集合屬性注入

2.3.1.   準備好相應的類屬性

// 簡單屬性

private Long id;

private String name;

private Boolean sex;

private BigDecimal salary;

 

// 對象屬性

private List<OtherBean> otherBeanList;

private Set<String> set;

private Set<OtherBean> otherBeanSet;

private Map<String,Object> map;

 

//下面這個是重點

private Properties props1;

private Properties props2;

private String[] arrays;

private List<String> list;

 

下面的都看一下,大概瞭解一下就好了

2.4.  數組(兩種方案-掌握):

2.4.1.   簡寫

<property name="arrays" value="A,B,C" />

2.4.2.   完整寫法

<property name="arrays">

         <array>

                  <value>xxx</value>

                  <value>yyy</value>

                  <value>zzz</value>

         </array>

</property>

2.5.  List<String>(瞭解)

<property name="list">

         <list>

                  <value>xxx</value>

                  <value>aaa</value>

                  <value>bbbb</value>

         </list>

</property>

2.6.  Set<String>(瞭解)

<property name="set">

         <set>

                  <value>xxx</value>

                  <value>aaa</value>

                  <value>bbbb</value>

         </set>

</property>

2.7.  List<OtherBean>(瞭解)

<property name="otherBeanList">

         <list>

                  <bean class="cn.itsource._01_.OtherBean" />

                  <bean class="cn.itsource._01_.OtherBean" />

                  <ref bean="otherBean" />

                  <ref bean="otherBean" />

         </list>

</property>

2.8.  Set<OtherBean>(瞭解)

<property name="otherBeanSet">

         <set>

                  <bean class="cn.itsource._01_.OtherBean" />

                  <bean class="cn.itsource._01_.OtherBean" />

                  <ref bean="otherBean" />

                  <ref bean="otherBean" />

         </set>

</property>

2.9.  Map(瞭解)

<property name="map">

         <map>

                  <entry key="xx" value="value1"></entry>

                  <entry key="yy" value="value2"></entry>

         </map>

</property>

2.10.         這裏是我們的重點部分,怎麼配置一個Properties對象:

2.10.1.        方案一:簡單,不支持中文

<property name="props1">

         <value>

                  Jpa.dialect=org.Jpa.dialect.HSQLDialect

                  Jpa.driverClassName=com.mysql.jdbc.Driver

         </value>

</property>

2.10.2.        方案二:支持中文

<property name="props2">

         <props>

                  <prop key="Jpa.dialect">org.Jpa.dialect.HSQLDialect</prop>

                  <prop key="Jpa.driverClassName">com.mysql.jdbc.Driver中文 </prop>

         </props>

</property>

  1. XML自動注入

使用XML自動注入,能夠簡化咱們XML的配置。

不過對於學習階段,並不建議你們這樣來使用。

3.1.  簡化spring的配置文件

3.1.1.   byName  按照屬性的名稱  setXxx方法  

         bean.id的名稱

3.1.2.   byType   按照注入對象的類型,要求:類型只能配置一個實例

           setXxx方法   注入類的類型(Class)

           和配置文件裏面的類型進行比較

           配置文件裏面的類型只能是1個

3.2.  配置方案

根節點beans   default-autowire="byName" 對當前配置文件的全部bean都生效

子節點bean autowire="byType"只對當前bean生效

  1. 全註解配置

在Java中寫Xml配置Bean仍是比較麻煩,所以,Spring還提供了使用註解來配置的文件。咱們能夠來看一下,註解是怎麼來配置這個Xml的

配置使用註解流程步驟

4.1.  配置context命名空間

<?xml version="1.0" encoding="UTF-8"?>

<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">

4.2.  第一步:配置讓Spring掃描類與支持註解

<!--

         @Component  普通倉庫

         @Repository  倉庫(其實就是dao層)

         @Service   service層

         @Controller  控制層(servlet、admin)

 -->

<!-- 進行包的掃描,去看類上面是否有相應的標籤配置 -->

<context:component-scan base-package="cn.itsource._03_anno" />

<!-- 這個不是必須的(spring3.2版本前使用) 配上後兼容性好 -->

<context:annotation-config />

4.3.  第二步:在類裏面加上註解

4.3.1.   Dao

@Repository

public class UserDao {

         public void save(){

                  System.out.println("保存數據xxxx....");

         }

}

4.3.2.   Service

@Service

public class UserService {

         @Autowired

         private UserDao userDao;

         public void save(){

                  userDao.save();

         }

}

4.3.3.   Action

@Controller

@Scope(「prototype」) 多例

public class UserAction {

         @Autowired

         private UserService userService;

         public String save(){

                  userService.save();

                  return "success";

         }

}

 

4.4.  註解配置bean的名稱

4.4.1.   接口有兩個實現(可能性比較少)

完成以後,你們注意,如今的配置還有一個問題,好比說我按真實狀況來一個Dao接口,而後這個接口有兩個實現,如今就會出問題

IUserDao  (UserJdbcDaoImpl/UserJpaDaoImpl)

而咱們聲明的時候就是使用了IUserDao

@Service

public class UserService {

         @Autowired

         private IUserDao userDao;

         public void save(){

                  userDao.save();

         }

}

此時會就出錯:由於Spring不知道你用的是哪個dao的實現

4.4.2.   解決的方案:爲dao生成的bean加上名稱,咱們在調用的時候肯定名稱便可。

@Repository("userJdbcDao")

public class UserJdbcDaoImpl  implements IUserDao{

         public void save(){

                  System.out.println("保存數據xxxx....");

         }

}

@Repository("userJpaDao")

public class UserJpaDaoImpl  implements IUserDao{

         public void save(){

                  System.out.println("保存數據xxxx....");

         }

}

4.5.  調用名稱兩套方案:

4.5.1.   方案一:使用@Autowired

@Service

public class UserService {

         @Autowired

         @Qualifier("userJdbcDao")

         private IUserDao userDao;

         public void save(){

                  userDao.save();

         }

}

 

4.5.2.   方案二:使用@Resource

@Service

public class UserService {

         @Resource(name="userJpaDao")

         private IUserDao userDao;

         public void save(){

                  userDao.save();

         }

}

 

4.6.  問題:使用哪種註解來解決比較好?

若是你用的是Spring的註解,儘可能所有使用Spring的註解標籤

 

  1. 使用xml版手動注入,xml自動注入仍是註解版?

初學使用xml版,手動注入

熟練以後可使用xml自動注入

之後趨勢:註解版

若是是註解版,就所有使用註解(本身寫的類),不要混用,其它框架已經寫好的類仍然使用xml進行配置

若是是xml版,在測試的使用必須使用註解注入(由於測試框架使用註解版)

 

只有本身寫的類,才能夠所有用註解,別人寫的類使用註解必須去修改別人的源碼,添加相應的註解標誌(不建議這樣搞)

  1. 代理模式

Aop利用代理模式實現功能加強

Aop可以作什麼?日誌管理,事務管理,權限控制

6.1.  定義

代理模式的英文叫作Proxy或Surrogate,中文均可譯爲」代理「,所謂代理,就是一我的或者一個機構表明另外一我的或者另外一個機構採起行動。在一些狀況下,一個客戶不想或者不可以直接引用一個對象,而代理對象能夠在客戶端和目標對象之間起到中介的做用

6.2.  三種角色

6.2.1.   抽象主題角色:

聲明瞭真實主題和代理主題的共同接口,這樣一來在任何可使用真實主題的地方均可以是使用代理主題

6.2.2.   代理主題(Proxy)角色:

代理主題角色內部含有對真實主題的引用,從而能夠在任什麼時候候操做真實主題對象;

代理主題角色提供一個與真實主題角色相同的接口,以即可以在任什麼時候候均可以替代真實主題控制對真實主題的引用,負責在須要的時候建立真實主題對象(和刪除真實主題對象);

代理角色一般在將客戶端調用傳遞給真實的主題以前或以後(前置加強/通知,後置加強/通知),都要執行某個操做,而不是單純地將調用傳遞給真實主題對象。

6.2.3.   真實主題角色:

定義了代理角色所表明地真實對象

 

 

6.3.  代理模式分類

靜態代理/動態代理

6.4.  靜態代理

6.4.1.   抽象主題角色

 

6.4.2.   真實主題角色

 

6.4.3.   代理主題角色:中介

代理主題角色內部含有對真實主題的引用

 

6.4.4.   調用方

 

若是有代理主題角色存在,必須修改調用方纔能實現代理

 

 

6.4.5.   靜態代理的小結

若是有n個接口,必然有n個實現,n個代理類:代碼很是多

6.5.  jdk動態代理

和靜態代理有相同的抽象主題角色,真實主題角色

JDK動態代理要求它代理的這個真實對象必需要實現某一個接口    

CGLIB 動態代理,真實對象能夠不實現接口

Spring中使用代理,若是這個類有接口,默認使用JDK的動態代理,若是這個類沒有接口,會使用CGLIB的動態代理

6.5.1.   代理主題角色

 

 

 

6.5.2.   調用方

 

 

6.5.3.   jdk動態代理小結

若是有n個接口,必然有n個實現,只用寫1個代理類JDKProxy就能夠對全部有接口進行處理

若是有代理主題角色存在,必須修改調用方纔能實現代理

6.6.  Cglib動態代理

Cglib相似於javassist-3.18.1-GA.jar功能字節碼加強,

原來Hibernate3.2以前就是使用cglib來進行字節碼加強

 

6.6.1.   代理主題角色

import org.springframework.cglib.proxy.Enhancer;

import org.springframework.cglib.proxy.MethodInterceptor;

import org.springframework.cglib.proxy.MethodProxy;

 

 

 

 

6.6.2.   cglib動態代理小結

只用寫1個代理類CglibProxy就能夠對全部沒有接口的而且不能是final類都進行處理

若是有代理主題角色存在,必須修改調用方纔能實現代理

  1. Spring的AOP

7.1.  早期aop都是spring本身實現,後來仍是用的標準aspects

AOP:面向切面編程

配置的三個元素(什麼時候,何地,執行什麼功能)

   什麼時候:在執行方法以前/以後/有異常...                        前置仍是後置,異常

   何地:在哪個包中的哪個類的哪個方法上面執行            切入點:哪一個包哪一個類哪一個方法

   作什麼事: 在UserServie中執行update方法以前添加日誌   加強/通知

7.2.  Spring有兩種代理方案:

7.2.1.   若目標對象實現了若干接口

spring使用JDK的java.lang.reflect.Proxy類代理。

7.2.2.   若目標對象沒有實現任何接口,

spring使用CGLIB庫生成目標對象的子類。

7.2.3.   使用該方案時須要注意:

 1.對接口建立代理優於對類建立代理,由於會產生更加鬆耦合的系統。

     對類代理是讓遺留系統或沒法實現接口的第三方類庫一樣能夠獲得通知,

            這種方案應該是備用方案。

 2.標記爲final的方法不可以被通知。spring是爲目標類產生子類。任何須要

             被通知的方法都被複寫,將通知織入。final方法是不容許重寫的。

7.3.  Xml版

7.3.1.   添加jar文件

aspects

spring-framework-4.1.2.RELEASE-dependencies\org.aopalliance\com.springsource.org.aopalliance\1.0.0\com.springsource.org.aopalliance-1.0.0.jar

 

 

spring-framework-4.1.2.RELEASE-dependencies\org.aspectj\com.springsource.org.aspectj.weaver\1.6.8.RELEASE\com.springsource.org.aspectj.weaver-1.6.8.RELEASE.jar

7.3.2.   添加aop命名空間

xmlns:aop="http://www.springframework.org/schema/aop"

http://www.springframework.org/schema/aop http://www.springframework.org/schema/aop/spring-aop.xsd

7.3.3.   前置加強(通知)

 

7.3.4.   後置加強,異常加強,最終加強

 

7.3.5.   環繞加強(前面的4個加強就不用了)

 

7.3.6.   環繞方法

import org.aspectj.lang.ProceedingJoinPoint;

 

 

7.4.  註解版

7.4.1.   配置文件

 

7.4.2.   事務管理器

 

 

 

7.4.3.   AOP中的概念

什麼叫作AOP:Aspect oritention programming(面向切面編程)

 

AOP當中的概念:

1,切入點Pointcut:在哪些類,哪些方法上面切(where);

2,加強,通知Advice(對應到一個方法):在方法的什麼時機(when)作什麼(what);

3,切面Aspect:切入點+通知

4,織入Weaving:把切面加入到對象,並建立出代理對象的過程.

相關文章
相關標籤/搜索