本文主要包含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 -> 選擇所有的選項。如圖:
點選finish,安裝完成之後,重新開機eclipse,然後建立一個java工程,應該出現下面的效果:
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
代碼如下:
/**
*
*/
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屬性:
運作整個工程,完成。