天天看點

貫穿spring的核心理念

本文主要包含spring架構的整個理念。

1.IoC(反轉控制)和依賴注入

2.面向方面程式設計

1.IoC(反轉控制)和依賴注入

參考這篇文章:http://www.bccn.net/Article/kfyy/java/jszl/200610/4512.html

使用IoC,對象是被動的接受依賴類,而不是自己主動的去找。容器在執行個體化的時候主動将它的依賴類注入給它。可以這樣了解:控制反轉将類的主動權轉移到接口上,依賴注入通過xml配置檔案在類執行個體化時将其依賴類注入。

2.面向方面程式設計

2.1 eclipse中面向方面程式設計開發環境。

2.2 面向方面程式設計簡介

2.3 一個簡單的AOP demo

2.1 eclipse中面向方面程式設計開發環境

windows -> install new softwares -> add a new website ->輸入下面的update site :http://download.eclipse.org/tools/ajdt/36/update -> 選擇所有的選項。如圖:

貫穿spring的核心理念

點選finish,安裝完成之後,重新開機eclipse,然後建立一個java工程,應該出現下面的效果:

貫穿spring的核心理念

2.2 面向方面簡介

在面向對象的程式設計中,主要是能夠解決的是一個對相集合之間的關系,通過繼承的政策實作代碼的重複使用。但是也存在oo無法解決的問題,當要為沒有類層次的對象引入公共行為的話,oo的思想是無法解決的,是以引入了面向方面程式設計。

面向方面關鍵概念:

join point:程式執行過程中某一點,advice就是相對于這個join point而言的。

advice : advice是join point的執行代碼,都是方面的“執行的邏輯”。

pointcut:一組join point的總稱,用于訓示某個建議應用于何處。

introduction:為現有的java類添加字段或者是方法。

before advice :在調用join point之前調用before advice。

after advice:和before advice相反。

2.3簡單的aop程式設計執行個體

2.3.1使用j2se的動态代理實作aop

用戶端代碼:

/**

*

*/

package aop.proxy;

import com.sun.org.apache.bcel.internal.generic.NEW;

/**

* 傳統實作,沒有使用aop架構

* @author jefferyxu

*

*/

public class BusinessLogicUsage {

/**

* @param args

*/

public static void main(String[] args) {

// TODO Auto-generated method stub

IBusinessLogic businessLogic =

(IBusinessLogic)LoggingProxyAspect.bind(SecurityProxyAspect.bind(new BusinessLogicCoreConcern()));

businessLogic.businessMethod1();

System.out.println();

businessLogic.businessMethod2();

}

}

BusinessLogicCoreConcern.java

package aop.proxy;

/**

* 傳統的做法 ,沒有使用aop架構

* @author jefferyxu

*

*/

public class BusinessLogicCoreConcern implements IBusinessLogic {

@Override

public void businessMethod1() {

// TODO Auto-generated method stub

doCoreBusiness1();

}

@Override

public void businessMethod2() {

// TODO Auto-generated method stub

doCoreBusiness2();

}

/**

* 執行核心業務1

*/

private void doCoreBusiness1() {

System.out.println("doCoreBusiness1");

}

/**

* 執行核心業務2

*/

private void doCoreBusiness2() {

System.out.println("doCoreBusiness2");

}

}

IBusinessLogic.java

/**

* @author jefferyxu

*/

package aop.proxy;

public interface IBusinessLogic {

public void businessMethod1();

public void businessMethod2();

}

LoggingProxyAspect.java

/**

*

*/

package aop.proxy;

import java.lang.reflect.InvocationHandler;

import java.lang.reflect.Method;

import java.lang.reflect.Proxy;

import sun.awt.geom.AreaOp.AddOp;

import sun.util.logging.resources.logging;

/**

* @author jefferyxu

*

*/

public class LoggingProxyAspect implements InvocationHandler{

private Object proxyobj;

@Override

public Object invoke(Object proxy, Method method, Object[] args)

throws Throwable {

// TODO Auto-generated method stub

beforeAdvice(method);

Object object = method.invoke(proxyobj, args);

afterAdvice(method);

return object;

}

public LoggingProxyAspect(Object obj) {

this.proxyobj = obj;

}

/**

* 通過動态代理生成動态對象

* @param object

* @return

*/

public static Object bind(Object object) {

Class cls = object.getClass();

return Proxy.newProxyInstance(cls.getClassLoader(), cls.getInterfaces(), new LoggingProxyAspect(object));

}

/**

* 調用前處理

* @param method

*/

private void beforeAdvice(Method method){

logging("before calling : " + method.getName());

}

/**

* 調用之後處理

* @param method

*/

private void afterAdvice(Method method) {

logging("after calling :" + method.getName());

}

private void logging(String str){

System.out.println(str);

}

}

SecurityProxyAspect.java :

/**

*

*/

package aop.proxy;

import java.lang.reflect.InvocationHandler;

import java.lang.reflect.Method;

import java.lang.reflect.Proxy;

/**

* @author xuqiang

*

*/

public class SecurityProxyAspect implements InvocationHandler {

private Object proxyobj;

/* (non-Javadoc)

* @see java.lang.reflect.InvocationHandler#invoke(java.lang.Object, java.lang.reflect.Method, java.lang.Object[])

*/

@Override

public Object invoke(Object arg0, Method method, Object[] args)

throws Throwable {

// TODO Auto-generated method stub

/**

* 這裡隻關聯到businessMethod1

*/

if(method.getName().equalsIgnoreCase("businessMethod1")) {

beforeAdvice(method);

}

Object object = method.invoke(proxyobj, args);

return object;

}

private void beforeAdvice(Method method) {

doSecurityCheck();

}

private void doSecurityCheck(){

System.out.println("doing security check");

}

/**

* @param args

*/

public static void main(String[] args) {

// TODO Auto-generated method stub

}

public SecurityProxyAspect(Object obj) {

this.proxyobj = obj;

}

/**

* 通過動态代理生成對象代理

* @param object

* @return

*/

public static Object bind(Object object) {

Class cls = object.getClass();

return Proxy.newProxyInstance(cls.getClassLoader(), cls.getInterfaces(), new SecurityProxyAspect(object));

}

}

上面的代碼使用的是java中的InvocationHandler實作的。簡單的講: Proxy類的設計用到代理模式的設計思想,Proxy類對象實作了代理目标的所有接口,并代替目标對象進行實際的操作。但這種替代不是一種簡單的替代, 這樣沒有任何意義,代理的目的是在目标對象方法的基礎上作增強,這種增強的本質通常就是對目标對象的方法進行攔截。是以,Proxy應該包括一個方法攔截 器,來訓示當攔截到方法調用時作何種處理。InvocationHandler就是攔截器的接口。(http://blog.csdn.net/pizishuai2008/archive/2009/07/28/4385906.aspx)。

也就是當接口的實作類或者是接口調用接口中的函數的時候,java會自動調用invoke(InvocationHandler接口中的一個待實作的函數)函數。預設的情況下,調用接口中的任何一個函數,都會觸發invoke函數被調用,但是可以在函數invoke中通過method的名稱來做限制,就像上面的做法:

if(method.getName().equalsIgnoreCase("businessMethod1")) {

beforeAdvice(method);

}

下面是一個簡單的使用InvocationHandler實作的例子:

IAnimal.java :

package proxytest;

public interface IAnimal {

void info();

}

Dog.java :

package proxytest;

public class Dog implements IAnimal

{

public void info() {

System.out.println("this is a dog!");

}

}

用戶端程式:

package proxytest;

import java.lang.reflect.*;

public class ProxyTest {

public static void main(String[] args) throws InterruptedException {

final IAnimal animal = new Dog();

Object proxyObj =Proxy.newProxyInstance(

animal.getClass().getClassLoader(),

animal.getClass().getInterfaces(),

/**

* 定義當proxyObj對象調用interface的接口時調用

* 的方法

*/

new InvocationHandler()

{

public Object invoke(Object proxy, Method method, Object[] args)

{

try {

System.out.println("被攔截的方法:" + method.getName());

return method.invoke(animal, args);

}

catch (IllegalArgumentException e) {

// TODO Auto-generated catch block

e.printStackTrace();

return null;

} catch (IllegalAccessException e) {

// TODO Auto-generated catch block

e.printStackTrace();

return null;

} catch (InvocationTargetException e) {

// TODO Auto-generated catch block

e.printStackTrace();

return null;

}

}

});

if(proxyObj instanceof IAnimal)

{

System.out.println("the proxyObj is an animal!");

}

else

{

System.out.println("the proxyObj isn't an animal!");

}

if(proxyObj instanceof Dog)

{

System.out.println("the proxyObj is a dog!");

}

else

{

System.out.println("the proxyObj isn't a dog!");

}

IAnimal animalProxy = (IAnimal)proxyObj;

//animalProxy.info();

//animalProxy.hashCode();

System.out.println(animalProxy.getClass().getName().toString());

}

}

2.3.2使用aspectj來實作上面的demo如下:

用戶端程式:

/**

*

*/

package aop.aspectj;

import aop.proxy.*;

/**

* @author jefferyxu

*

*/

public class BusinessLogicUsage {

/**

* @param args

*/

public static void main(String[] args) {

// TODO Auto-generated method stub

IBusinessLogic businessLogic = new BusinessLogicCoreConcern();

businessLogic.businessMethod1();

System.out.println();

businessLogic.businessMethod2();

}

}

SecurityAspect.java :  新增加一個aspect

貫穿spring的核心理念

代碼如下:

/**

*

*/

package aop.aspectj;

import aop.proxy.*;

/**

* @author jefferyxu

*

*/

public aspect SecurityAspect {

private pointcut securityExecution():

execution(public void IBusinessLogic.businessMethod1());

// 聲明join point,定義在何時調用函數before和after

// 聲明before advice

before() : securityExecution() {

doSecurityCheck();

}

private void doSecurityCheck() {

System.out.println("doing security check");

}

}

TranscationAspect.java :

/**

*

*/

package aop.aspectj;

import aop.proxy.*;

/**

* @author xuqiang

*

*/

public aspect TranscationAspect {

/**

* 定義切入點

*/

private pointcut transcationExecution() :

execution(public void IBusinessLogic.businessMethod1()) ||

execution(public void IBusinessLogic.businessMethod2());

/**

* 定義before advice

*/

before() : transcationExecution() {

start();

};

/**

* 定義after advice

*/

after() : transcationExecution() {

commit();

}

/**

* 模拟transacation

*/

private void start() {

System.out.println("transcation start");

}

private void commit() {

System.out.println("transcation commit");

}

}

給整個工程添加aspectj屬性:

貫穿spring的核心理念

運作整個工程,完成。