最最簡單的spring及AOP實例

 1、簡單的spring實現(annotation方式)spring

bean類express

package hello;

import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;

@Configuration
public class HelloWorld {
	private String Msg;

	public void Hello() {
		System.out.println("Hello:" + Msg);
	}

	@Bean(name = "helloworldbean")
	public HelloWorld helloWorldBean() {
		HelloWorld hw = new HelloWorld();
		hw.Msg = "How are you ?";
		return hw;
	}

}

測試類:segmentfault

package hello;

import org.springframework.context.ApplicationContext;
import org.springframework.context.annotation.AnnotationConfigApplicationContext;

public class TestHelloWorld {
	/**
	 * @param args
	 */
	private static ApplicationContext ctx;

	public static void main(String[] args) {
		// TODO 自動生成的方法存根
		ctx =  new AnnotationConfigApplicationContext(HelloWorld.class);
		
		HelloWorld helloWorld = (HelloWorld) ctx.getBean("helloworldbean");
		helloWorld.Hello();
	}
}

運行結果:app

2017-10-24 00:34:15 [org.springframework.context.annotation.AnnotationConfigApplicationContext]-[INFO] Refreshing org.springframework.context.annotation.AnnotationConfigApplicationContext@12bb4df8: startup date [Tue Oct 24 00:34:15 CST 2017]; root of context hierarchy
Hello:How are you ?

(xml方式)模塊化

bean類函數

package com.hello;

public class XmlHello {
	private String name;

	public void setName(String name) {
		this.name = name;
	}

	public void printHello() {
		System.out.println("Spring  : Hello ! " + name);
	}
}

xml配置文件applicationContext.xml(放在包com.hello下)測試

<beans xmlns="http://www.springframework.org/schema/beans"
	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-4.3.xsd">

	<bean id="helloBean" class="com.hello.XmlHello">
		<property name="name" value="Yiibai" />
	</bean>

</beans>

測試類:this

package com.hello;


import org.springframework.context.ApplicationContext;
import org.springframework.context.support.ClassPathXmlApplicationContext;

public class AppXmlHello {
	/**
	 * @param args
	 */
	private static ApplicationContext ctx;

	public static void main(String[] args) {
		// TODO 自動生成的方法存根
		ctx =  new ClassPathXmlApplicationContext(
				"com/hello/applicationContext.xml");
		
		XmlHello helloWorld = (XmlHello) ctx.getBean("helloBean");
		helloWorld.printHello();;
	}
}

2、註解方式實現aop(須要導入aspectjrt-1.8.11.jar,aspectjweaver-1.8.11.jar  ):spa

package hello;

import org.aspectj.lang.annotation.AfterReturning;
import org.aspectj.lang.annotation.Aspect;
import org.aspectj.lang.annotation.Before;
import org.aspectj.lang.annotation.Pointcut;
import org.springframework.stereotype.Component;

@Component
@Aspect
public class HelloAop {

	// 聲明切點
	@Pointcut("execution(* *.Hello())")
	public void pointcut() {
	}

	@Before("pointcut()")
	public void beforepoint() {
		System.out.println("接下去調用Hello()......");
	}

	@AfterReturning("pointcut()")
	public void afterhello() {
		System.out.println("函數Hello()執行結束......");
	}

}

 bean類HelloWorld(@Configuration後)加上:代理

@ComponentScan
@EnableAspectJAutoProxy

 TestHelloWorld類不變,運行結果以下 :

2017-11-20 00:23:05 [org.springframework.context.annotation.AnnotationConfigApplicationContext]-[INFO] Refreshing org.springframework.context.annotation.AnnotationConfigApplicationContext@12bb4df8: startup date [Mon Nov 20 00:23:05 CST 2017]; root of context hierarchy
接下去調用Hello()......
Hello:How are you ?
函數Hello()執行結束......

 

(轉)spring的AOP機制

前言

在軟件開發中,散佈於應用中多處的功能被稱爲橫切關注點,一般來說,這些橫切關注點從概念上是與應用的業務邏輯相分離的。把這些橫切關注點和業務邏輯分離出來正是AOP要解決的問題。AOP可以幫咱們模塊化橫切關注點,換言之,橫切關注點能夠被描述爲影響應用多出的功能。這些橫切點被模塊化特殊的類,這些類被稱爲切面。

術語定義

通知:切面有必需要完成的工做,在AOP中,切面的工做被稱爲通知。通知定義了切面是什麼以及什麼時候使用,除了描述切面要完成的工做,通知還解決了什麼時候執行這個工做的問題,它應該在某個方法以前?以後?以前和以後都調用?仍是隻在方法拋出異常時調用?

鏈接點:鏈接點是應用程序執行過程當中,可以插入切面的一個點。

切點:是在鏈接點的基礎上定義切點,比方說一個類由十幾個方法,每一個方法的調用前和調用後均可以插入通知,可是你只想選擇幾個方法插入通知,所以你定義一個切點來選擇你想插入的通知的方法。

切面:切面就是通知和切點的結合。

織入:織入是把切面應用到目標對象並建立新的代理對象的過程,切面在指定的鏈接點被織入到目標對象中。在目標對象的生命週期裏有多個點能夠進行織入:編譯期、類加載期、運行期。其中編譯器織入須要特殊的編譯器,類加載器織入須要特殊的類加載器,spring的AOP 是在運行期織入通知的。

Spring的AOP支持

spring提供了AOP的四種支持,分別是:基於代理的經典Spring AOP模式;純POJO切面;@AspectJ註解驅動的切面;@注入式AspectJ切面。spring所建立的通知都是用標準的Java類編寫的,並且定義通知所應用的切點一般會使用註解或在Spring配置文件裏採用XML來編寫。

spring只支持方法級別的鏈接點。
在spring AOP中,要使用AspectJ的切點表達式語言來定義切點,關於Spring AOP的AspectJ切點,最重要的一點就是Spring僅支持AspectJ切點指示器的一個子集:
1.arg() 限制鏈接點匹配參數爲指定類型的執行方法;
2.@args() 限制鏈接點匹配參數由指定註解標註的執行方法;
3.execution() 用於匹配是鏈接點的執行方法;
4.this() 限制鏈接點匹配AOP代理的bean引用爲指定類型的類
5.target 限制鏈接點匹配目標對象爲指定類型的類
6.@target() 限制鏈接點匹配特定的執行對象,這些對象對應的類要具備指定類型的註解
7.within() 限制鏈接點匹配指定的類型
8.@within() 限制鏈接點匹配特定註解所標註的類型
9.@annotation 限定匹配帶有指定註解的鏈接點

spring 註解建立切面

目標對象:

package concert;
public interface Performance{
    public void perform();
}

切面對象:

package concert;

@Aspect//表示Audience的實例是一個切面
public class Audience{
    @Before("execution(**concert.Performance.perform(..))")
    public void silenceCellPhones(){
    //在perfrom方法執行以前
    }
    @Before("execution(**concert.Performance.perform(..))")
    public void takeSeats(){
    //在perfrom方法執行以前
    }
    @AfterReturning("execution(**concert.Performance.perform(..))")
    public void silenceCellPhones(){
    //在perfrom方法執行以後
    }
    @AfterThrowing("execution(**concert.Performance.perform(..))")
    public void silenceCellPhones(){
    //在perfrom方法拋出異常以後
    }
}

上面的類中切點表達式execution(**concert.Performance.perform(..))屢次出現,咱們也能夠經過@Pointcut註解避免每次都寫很長的切點表可是以下所示:

@Aspect//表示Audience的實例是一個切面
public class Audience{
    @Pointcut("execution(**concert.Performance.perform(..))")
    public void performance(){}
    @Before("performance()")
    public void silenceCellPhones(){
    //在perfrom方法執行以前
    }
    @Before("performance()")
    public void takeSeats(){
    //在perfrom方法執行以前
    }
    @AfterReturning("performance()")
    public void silenceCellPhones(){
    //在perfrom方法執行以後
    }
    @AfterThrowing("performance()")
    public void silenceCellPhones(){
    //在perfrom方法拋出異常以後
    }
}

接下來須要在配置文件中配置切面以下所示:

@Configuration
@EnableAspectJAutoProxy//啓動AspectJ自動代理
@ComponentScan
public class ConcertConfig{
}
//或者在配置文件中配置中添加
<aop:aspectj-autoproxy />
表示啓動切面代理

環繞通知:

@Aspect//表示Audience的實例是一個切面
public class Audience{
    @Pointcut("execution(**concert.Performance.perform(..))")
    public void performance(){}
    
    @Before("performance()")
    public void watchPerformance(ProceedingJoinPoint jp){
        //在方法以前執行
        System.out.println(" beform the method is invoked");
        jp.proceed()//控制權交給目標方法
        //在方法以後執行
        System.out.println(" after the method is invoked");
    }
    
}

處理通知中的參數

public class Audience{
    @Pointcut("execution(**concert.Performance.perform(int))&&args(trackNumber)")
    public void performance(){}
    
    @Before("performance(trackNumber)")
    public void watchPerformance(int trackNumber){
        //截獲傳遞給目標方法的參數並傳遞給切面中處理方法
        System.out.println(trackNumber);
    }
    
}

xml中聲明切面

spring AOP提供的xml配置元素:
1.<aop:advisor> 定義AOP通知;
2.<aop:after> 後置通知;
3.<aop:after-returning> 返回通知
4.<aop:around> 環繞通知
5.<aop:aspect> 定義一個切面
6.<aop:aspectj-autoproxy> 啓用切面註解驅動
7.<aop:before> 前置通知
8.<aop:config> 頂層的AOP配置元素;
9.<aop:pointcut>:定義個切點

<aop:config>
    <aop:aspect ref="audience">
        <aop:before
          pointcut="execution(**concert.Performance.perform())" method="silenceCellPhones"/>
          <aop:before
          pointcut="execution(**concert.Performance.perform())" method="takeSeats"/>
         <aop:after-returning
          pointcut="execution(**concert.Performance.perform())" method="applause"/>
         <aop:after-throwing
          pointcut="execution(**concert.Performance.perform())" method="demandRefund"/>

    </aop:aspect>
</aop config>

定義切點:

<aop:config>
    <aop:aspect ref="audience">
        <aop:pointcut id="performance" expression="execution(**concert.Performance.perform())">
        <aop:before
          pointcut-ref="performance" method="silenceCellPhones"/>
          <aop:before
          pointcut="performance" method="takeSeats"/>
         <aop:after-returning
          pointcut="performance" method="applause"/>
         <aop:after-throwing
          pointcut="performance" method="demandRefund"/>

    </aop:aspect>
</aop config>
相關文章
相關標籤/搜索