Spring实战读书笔记 第四章 面向切面的Spring

1,AOP术语
    -1,通知(advice):通知定义了切面是什么时候以及何时用的。除了描述切面的工作,通知还决定了合适解决。Spring切面可以用5中类型的通知。
    Before:在方法调用之前使用。
    After:在方法完成之后调用通知,无论方法是否执行成功。
    After-returning:在方法执行成功后调用。
    After-throwing:在方法抛出异常后调用。
    Around:通知包裹了被通知的方法,在被通知的方法调用之前和调用之后执行自定义行为。
    -2,切点(pointcut):一个或多个连接点。
    -3,连接点(join point):应用在执行过程中能够插入切面的点。
    -4,切面(Aspect):切面是通知和切点的结合,通知和切点共同定义了关于切面的全部内容。
    -5,引入(Introduction):引入允许我们向现有的类添加新的方法或属性。
2,Spring借助AspectJ的切点表达式语言来定义Spring切面
    -1,arg() :限制连接点匹配参数为制定类型的执行方法。
    -2,@args() :限制连接点匹配参数由制定注解标注的执行方法。
    -3,execution():用于匹配是连接点的执行方法。
    -4,this():限制连接点匹配AOP代理的Bean引用为制定类型的类。
    -5,target():限制连接点匹配目标对象为制定类型的类。
    -6,@target():限制连接点匹配特定的执行对象,这些对象对应的类要具备制定注解。
    -7,within():限制连接点匹配指定的类型。
    -8,@within():限制连接点匹配制定注解的类型。
    -9,@annotation:限制匹配带有制定注解连接点。
3,编写切点:

<aop:config>
<aop:aspect ref="audience">
<aop:before
pointcut="execution(* chp02.springdol.Perform.perform(..))"
method="takeSeat" />
<aop:before
pointcut="execution(* chp02.springdol.Perform.perform(..))"
method="turnOffCellPhone" />
<aop:after-returning
pointcut="execution(* chp02.springdol.Perform.perform(..))"
method="applaud" />
<aop:after-throwing
pointcut="execution(* chp02.springdol.Perform.perform(..))"
method="demandRefund" />
aop:aspect>
aop:config>

package chp04.aop;
 
/**
* 类描述:观众类,测试AOP
*
* @author: Jing
* History: Jan 7, 2015 3:33:35 PM Jing Created.
*
*/
public class Audience {
public void takeSeat(){
System.out.println("The audience is taking their seats.");
}
public void turnOffCellPhone(){
System.out.println("The audience is turning off their cellphone!");
}
public void applaud(){
System.out.println("CLAP CLAP CLAP CLAP CLAP ");
}
public void demandRefund(){
System.out.println("Boo! we want our money back!");
}
}

package chp04.aop;
 
import org.springframework.context.ApplicationContext;
import org.springframework.context.support.ClassPathXmlApplicationContext;
 
import chp02.springdol.Perform;
 
/**
* 类描述:
*
* @author: Jing
* History: Jan 8, 2015 4:52:20 PM Jing Created.
*
*/
public class Main {
 
public static void main(String[] args) {
ApplicationContext ctx = new ClassPathXmlApplicationContext("chp04/aop/spring.xml");
 
Perform perform = (Perform) ctx.getBean("juggler");
perform.perform();
}
}


输出结果
The audience is taking their seats.
The audience is turning off their cellphone!
Juggler perform(),beanBags : 3
CLAP CLAP CLAP CLAP CLAP
因为以上涉及到的切点都相同,我们可以将切点配置抽取,如下:

<aop:config>
 
<aop:aspect ref="audience">
<aop:pointcut id="perform"
expression="execution(* chp02.springdol.Perform.perform(..))" />
<aop:before pointcut-ref="perform" method="takeSeat" />
<aop:before pointcut-ref="perform"
method="turnOffCellPhone" />
<aop:after-returning pointcut-ref="perform"
method="applaud" />
<aop:after-throwing pointcut-ref="perform"
method="demandRefund" />
aop:aspect>
aop:config>
声明环绕通知
    环绕通知java处理代码:

/**
*
* 方法说明:环绕通知
*
* Author: Jing Create Date: Jan 9, 2015 10:44:37 AM
*/
public void watchPerformance(ProceedingJoinPoint joinPoint) {
try {
 
System.out.println("The audience is taking their seats.");
System.out.println("The audience is turning off their cellphone!");
long start = System.currentTimeMillis();
 
joinPoint.proceed();
long end = System.currentTimeMillis();
System.out.println("CLAP!CLAP!CLAP!CLAP!");
System.out.println("The perform took " + ( end - start) + " s");
} catch (Throwable e) {
 
System.out.println("Exception, we want our money back! ");
}
 
}
环绕通知XML配置:

 
<aop:config>
<aop:aspect ref="audience">
<aop:pointcut id="perform2"
expression="execution(* chp02.springdol.Perform.perform(..))" />
<aop:around pointcut-ref="perform2"
method="watchPerformance" />
aop:aspect>
aop:config>
为通知传递参数:

package chp04.aop;
 
/**
* 类描述:测试通知参数
*
* @author: Jing
* History: Jan 9, 2015 11:00:32 AM Jing Created.
*
*/
public interface MindReader {
void interceptThoughts(String thoughts);
String getThoughts();
}

package chp04.aop;
 
/**
* 类描述:
*
* @author: Jing
* History: Jan 9, 2015 2:13:29 PM Jing Created.
*
*/
public class Magician implements MindReader{
 
private String thoughts;
 
public String getThoughts() {
return thoughts;
}
 
public void setThoughts(String throughts) {
this.thoughts = throughts;
}
 
@Override
public void interceptThoughts(String throughts) {
 
System.out.println("intercept Thoughts");
this.thoughts = throughts;
}
}

package chp04.aop;
 
/**
* 类描述:
*
* @author: Jing
* History: Jan 9, 2015 2:26:51 PM Jing Created.
*
*/
public interface Thinker {
 
void thinkOfSomething(String thoughts);
public String getThoughts();
}

package chp04.aop;
 
/**
* 类描述:
*
* @author: Jing
* History: Jan 9, 2015 2:27:48 PM Jing Created.
*
*/
public class Volunteer implements Thinker {
private String thoughts;
 
@Override
public void thinkOfSomething(String thoughts) {
this.thoughts = thoughts;
}
 
public String getThoughts() {
return thoughts;
}
 
}

<bean id="volunteer" class="chp04.aop.Volunteer" />
<bean id="magician" class="chp04.aop.Magician" />
 
<aop:config>
<aop:aspect ref="magician">
<aop:pointcut id="thinking" expression="execution(* chp04.aop.Thinker.thinkOfSomething(String)) and args(thoughts)"/>
<aop:before pointcut-ref="thinking" method="interceptThoughts" arg-names="thoughts"/>
aop:aspect>
aop:config>

package chp04.aop;
 
import org.springframework.context.ApplicationContext;
import org.springframework.context.support.ClassPathXmlApplicationContext;
 
/**
* 类描述:
*
* @author: Jing
* History: Jan 8, 2015 4:52:20 PM Jing Created.
*/
public class Main {
 
public static void main(String[] args) {
ApplicationContext ctx = new ClassPathXmlApplicationContext("chp04/aop/spring.xml");
 
// Volunteer volunteer = (Volunteer) ctx.getBean("volunteer");
// volunteer.thinkOfSomething("Thinking the world!");
Thinker volunteer = (Thinker) ctx.getBean("volunteer");//因为AOP配置,此处必须转换为接口
volunteer.thinkOfSomething("Thinking the world!");
System.out.println(volunteer.getThoughts());
}
}
4,通过切面引入新功能。

package chp04.aop;
 
/**
* 类描述:其他功能接口
*
* @author: Jing
* History: Jan 9, 2015 3:15:40 PM Jing Created.
*
*/
public interface Contestant {
 
void receiveAward();
}

package chp04.aop;
 
/**
* 类描述:接口实现
*
* @author: Jing
* History: Jan 9, 2015 3:25:47 PM Jing Created.
*
*/
public class GraciousContestant implements Contestant{
 
@Override
public void receiveAward() {
System.out.println("Auto Add method");
}
 
}

<bean id="graciousContestant" class="chp04.aop.GraciousContestant" />
<aop:config>
<aop:aspect>
<aop:declare-parents types-matching="chp04.aop.Thinker+"
implement-interface="chp04.aop.Contestant"
delegate-ref="graciousContestant" />
aop:aspect>
aop:config>

package chp04.aop;
 
import org.springframework.context.ApplicationContext;
import org.springframework.context.support.ClassPathXmlApplicationContext;
 
/**
* 类描述:
*
* @author: Jing
* History: Jan 8, 2015 4:52:20 PM Jing Created.
*/
public class Main {
 
public static void main(String[] args) {
ApplicationContext ctx = new ClassPathXmlApplicationContext("chp04/aop/spring.xml");
 
 
Contestant volunteer = (Contestant) ctx.getBean("volunteer");
volunteer.receiveAward();
}
}
5,基于注解的配置

 
package chp04.aop;
 
import org.aspectj.lang.ProceedingJoinPoint;
import org.aspectj.lang.annotation.AfterReturning;
import org.aspectj.lang.annotation.AfterThrowing;
import org.aspectj.lang.annotation.Aspect;
import org.aspectj.lang.annotation.Before;
import org.aspectj.lang.annotation.Pointcut;
 
/**
* 类描述:观众类,测试AOP
*
* @author: Jing History: Jan 7, 2015 3:33:35 PM Jing Created.
*
*/
@Aspect
public class Audience {
@Pointcut("execution(* chp02.springdol.Perform.perform(..))")
/**
* 定义切点
*/
public void perform(){
}
@Before("perform()")
public void takeSeat() {
 
System.out.println("The audience is taking their seats.");
}
@Before("perform()")
public void turnOffCellPhone() {
 
System.out.println("The audience is turning off their cellphone!");
}
@AfterReturning("perform()")
public void applaud() {
 
System.out.println("CLAP CLAP CLAP CLAP CLAP ");
}
@AfterThrowing("perform()")
public void demandRefund() {
 
System.out.println("Boo! we want our money back!");
}
 
/**
*
* 方法说明:环绕通知
*
* Author: Jing Create Date: Jan 9, 2015 10:44:37 AM
*/
public void watchPerformance(ProceedingJoinPoint joinPoint) {
try {
 
System.out.println("The audience is taking their seats.");
System.out.println("The audience is turning off their cellphone!");
long start = System.currentTimeMillis();
 
joinPoint.proceed();
long end = System.currentTimeMillis();
System.out.println("CLAP!CLAP!CLAP!CLAP!");
System.out.println("The perform took " + ( end - start) + " s");
} catch (Throwable e) {
 
System.out.println("Exception, we want our money back! ");
}
 
}
 
}
配置文件启用注解API

<aop:aspectj-autoproxy />
环绕通知:

 
/**
*
* 方法说明:环绕通知
*
* Author: Jing Create Date: Jan 9, 2015 10:44:37 AM
*/
@Around("perform()")
public void watchPerformance(ProceedingJoinPoint joinPoint) {
try {
 
System.out.println("The audience is taking their seats.");
System.out.println("The audience is turning off their cellphone!");
long start = System.currentTimeMillis();
 
joinPoint.proceed();
long end = System.currentTimeMillis();
System.out.println("CLAP!CLAP!CLAP!CLAP!");
System.out.println("The perform took " + ( end - start) + " s");
} catch (Throwable e) {
 
System.out.println("Exception, we want our money back! ");
}
 
}











































转载于:https://www.cnblogs.com/jingLongJun/p/4491059.html

你可能感兴趣的:(java)