1. 程式人生 > 其它 >Spring IOC\AOP\Bean

Spring IOC\AOP\Bean

Spring是一個輕量級的控制反轉IOC和麵向切面程式設計AOP的框架

Spring 自帶 IoC(Inverse of Control:控制反轉) 和 AOP(Aspect-Oriented Programming:面向切面程式設計)、可以很方便地對資料庫進行訪問、可以很方便地整合第三方元件(電子郵件,任務,排程,快取等等)、對單元測試支援比較好、支援 RESTful Java 應用程式的開發。

ApplicationContext作為Spring容器,Bean在ApplicationContext容器中

 

1、控制反轉IOC

是一種思想:兩方之間不互相依賴,由第三方容器來管理相關資源。

ioc實現基礎包:org.springframework.beans

org.springframework.context

(1)控制:物件建立、例項化、屬性賦值、物件間關係管理的權利

(2)反轉:控制權交由Spring框架、IOC容器,由這些容器來建立管理物件 例:Tomcat 建立servlet物件

(3)好處:物件之間解耦、降低依賴;資源容易管理

(4)實現方式:依賴注入(DI注入) 建立物件,給屬性賦值

= DI注入的方式(可用xml配置檔案 可用註解)

==1、構造注入

spring呼叫類的有引數構造方法 建立物件並完成賦值

==2、set注入(經常使用)

spring呼叫類的set方法 實現屬性的賦值

==3、擴充套件方式注入(p名稱空間、c名稱空間)

p名稱空間注入:可以直接注入屬性的值property

c名稱空間注入:構造器注入 construct-arg

匯入約束xmlns:p="http://www.springframework.org/schema/p"
<!--p名稱空間注入:可以直接注入屬性的值 property-->
   <bean id="user" class="com.qifengle.pojo.User" p:name="禾下涼" p:age="22"/>

匯入約束xmlns:c="http://www.springframework.org/schema/c"
<!--c名稱空間注入:構造器注入 construct-arg-->
<bean id="admin" class="com.qifengle.pojo.Admin" c:aname="禾下涼" c:apwd="666"/>

 

2、面向切面程式設計AOP

是OOP(面向物件程式設計)的一種延續。

相比較OOP抽取出橫切邏輯程式碼業務邏輯程式碼,根本上解耦,避免邏輯程式碼重複。

(1)基於動態代理(JDK動態代理 | CGLIB動態代理)

=當要代理的物件實現了某個介面,AOP會使用JDK Proxy;(必須實現介面)

=當要代理的物件沒有實現介面,AOP會使用CGLIB Proxy 生成一個被代理物件的子類來作為代理(原理是繼承)

(2)aop技術實現的框架

=Spring 屬於執行時增強、基於動態代理

=AspectJ 屬於編譯時增強、基於位元組碼操作

     ==實現方式:1、使用XML的配置檔案 配置全域性事務

                           2、使用註解(一般的使用方式)

     ==使用:1、切面的執行時間(Advice) 用註解表示  @Before、@AfterReturning、@Around、@AfterThrowing、@After

                    2、切面執行位置 切入點表示式

切入點表示式:execution(訪問許可權 方法返回值 方法宣告(引數) 異常裂隙)

execution(* set*(..)) 指定切入點為:任意一個以“set”開始的方法

execution(* com.qifenle.service..(..)):包.類.方法 指定切入點為:定義在service包裡的任意類,每個類中的任意方法

=切面多的情況下,最好使用AspectJ ,功能更強大,更快

(3)面向切面程式設計 切面是什麼?

非業務方法,給目標類增加的功能,獨立使用的(如時間、事務功能、日誌、許可權驗證等)

(4)切面的執行位置和執行時間

       =切面 Aspect 要增強的功能程式碼

       =連線點 JoinPoint 連線業務方法和切面的位置的方法

       =切入點 Poincut 多個連線點的集合 切面執行的位置

       =目標物件 給目標物件的方法增加功能 , 這個類就是目標物件

       =通知 Advice 表示切面功能執行的時間 目標方法執行前或後

 

3、spring Bean

(1)Bean: 指被ioc容器所管理的物件

(2)bean的作用域

      =1、singleton:單例bean例項 spring預設bean是單例的(單例模式的應用)

      =2、prototype: 每次請求都會建立一個新的bean例項

      =3、request: 每次HTTP請求都會產生一個新的bean,僅當前request請求週期內有效

      =4、session:每次新的session的HTTP請求都會產生一個新的bean,僅當前HTTP的session週期內有效

配置bean的作用域(xml方式)
<bean id="..." class="..." scope="singleton"></bean>
@Bean
@Scope(value = ConfigurableBeanFactory.SCOPE_PROTOTYPE)
public Person personPrototype() {
   return new Person();
}

(3)bean的三種裝配方式

     =1、byName自動裝配

   <!--    autowire="byName" 自動裝配
      自動在容器中查詢 物件對應的set方法set後面的值 對應的 bean id
      setCat ——》 id="cat"
      setDog ——》 id="dog"
-->
  <bean id="people" class="com.qifengle.pojo.People" autowire="byName">
      <property name="name" value="禾下涼"/>
  </bean>

    =2、byType自動裝配

  <!--      autowire="byType"  自動裝配
      自動在容器中查詢 物件屬性型別相同的 bean 但有唯一性  
      class="com.qifengle.pojo.Cat" ——》 id="cat" 可以不用id=“cat” <bean class="com.qifengle.pojo.Cat"/>
      class="com.qifengle.pojo.Dog" ——》 id="dog" 可以不用id=“dog” <bean class="com.qifengle.pojo.Dog"/>
      class="com.qifengle.pojo.Dog" ——》 id="dog1" 只有一個Dog屬性型別 但對應兩個id 則報錯
-->
 <bean id="people" class="com.qifengle.pojo.People" autowire="byType">
     <property name="name" value="禾下涼"/>
 </bean>

    =3、自動裝配註解

@Autowired 通過byType再通過byname的方式實現,而且必須要求這個物件存在 有時需要@Qualifier(value="id")指定id

@Resource預設通過byName的方式實現,如果通過byName實現不了 則通過byType實現 兩個都實現不了則報錯

(4)註解的區別:

宣告一個類為Bean的註解有:

@Autowired 自動裝配

@Component 通用的註解,可將任意類作為bean交由spring管理

@Repository 持久層註解 Dao|Mapper層 主要用於資料庫相關操作

@Service 服務層註解 邏輯程式碼操作

@Controller 控制層操作 主要用於使用者請求和接收Service層返回的資料給前端

    =1、@Component 作用於類,放在類上說明這個類被spring容器管理了

通過類路徑掃碼自動裝配到spring的bean容器中

   =2、@ComponentScan 作用於類

可以自定義要掃描的路徑

   =3、@Bean 作用於方法

標註在方法上,將該例項裝配到spring的bean容器中

比@Component自定義性更強,第三方類庫的類裝配到spring容器中經常使用

   =4、@Value 作用在set方法或屬性上

@Value("禾下涼")//相當於<property name="name" value="禾下涼"/>

(2)bean的生命週期

  =1、例項化bean物件

  =2、設定物件屬性 利用set()方法設定

  =3、實現檢查*Aware介面,若實現便呼叫相關的set方法,傳入相關的物件例項。例:

     ==實現了BeanNameAware介面,呼叫setBeanName(),傳入Bean的名字

     ==實現了BeanClassLoaderAware介面,呼叫setBeanClassLoader(),傳入ClassLoader物件例項

     ==實現了BeanFactoryAware介面,呼叫setBeanFactory(),傳入BeanFactory物件例項

  =4、BeanPostProcessor物件前置處理,執行postProcessBeforeInitialization()方法

  =5、檢查是否實現InitializingBean即可,有就呼叫afterPropertiesSet()方法

  =6、檢查是否配置有包含自定義init-method屬性,有,執行指定方法

  =7、BeanPostProcessor物件後置處理,執行postProcessAfterInitialization()方法

  =8、Bean使用階段

  =9、銷燬Bean,如果bean實現了DisposableBean介面,執行destroy()方法

  =10、銷燬Bean,如果配置檔案中有定義包含destroy-method屬性,執行指定方法