Spring学习笔记(5)---AOP之声明切面

[b]AOP中一些概念[/b]

[b]Aspect(切面):[/b]指横切性关注点的抽象即为切面,它与类相似,只是两者的关注点不一样,类是对物体特征的抽象,而切面横切性关注点的抽象.

[b]joinpoint(连接点):[/b]所谓连接点是指那些被拦截到的点。在spring中,这些点指的是方法,因为spring只支持方法类型的连接点,实际上joinpoint还可以是field或类构造器)

[b]Pointcut(切入点):[/b]所谓切入点是指我们要对那些joinpoint进行拦截的定义.

[b]Advice(通知):[/b]所谓通知是指拦截到joinpoint之后所要做的事情就是通知.通知分为前置通知,后置通知,异常通知,最终通知,环绕通知

[b]Target(目标对象)[/b]:代理的目标对象

[b]Weave(织入):[/b]指将aspects应用到target对象并导致proxy对象创建的过程称为织入.

[b]Introduction(引入):[/b]在不修改类代码的前提下, Introduction可以在运行期为类动态地添加一些方法或Field.

[color=red]光看这些定义是很难理解的,所以需要在例子中去消化。[/color]

要进行AOP编程,首先我们要在spring的配置文件中引入aop命名空间:
<beans xmlns="http://www.springframework.org/schema/beans"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xmlns:aop="http://www.springframework.org/schema/aop"
xsi:schemaLocation="http://www.springframework.org/schema/beans
http://www.springframework.org/schema/beans/spring-beans-2.5.xsd
http://www.springframework.org/schema/aop http://www.springframework.org/schema/aop/spring-aop-2.5.xsd">
</beans>


Spring提供了两种切面声明方式,实际工作中我们可以选用其中一种:
基于XML配置方式声明切面。
基于注解方式声明切面。

一,先来基于注解方式声明切面
1.Person类
package com.jzkangta.demo;

public class Person {

private int userId;
private String userName;
public int getUserId() {
return userId;
}
public void setUserId(int userId) {
this.userId = userId;
}
public String getUserName() {
return userName;
}
public void setUserName(String userName) {
this.userName = userName;
}
}

2.代理对象类
package com.jzkangta.demo;

public class PersonService {

public void save(int userId,String userName){
System.out.println("save user ----->userId="+userId+",userName="+userName);
}
public void delete(int userId){
System.out.println("delete user ----->userId="+userId);
}
public void update(int userId,String userName){
System.out.println("update user ----->userId="+userId+",userName="+userName);
}
public Person find(int userId){
System.out.println("find user ----->userId="+userId);
return null;
}
}


3.切面类
package com.jzkangta.demo;

import org.aspectj.lang.annotation.Aspect;
import org.aspectj.lang.annotation.Before;
import org.aspectj.lang.annotation.Pointcut;

/**
* 这是一个切面类
* 切面指横切性关注点的抽象即为切面,它与类相似,只是两者的关注点不一样,
* 类是对物体特征的抽象,而切面横切性关注点的抽象
* @author Administrator
*
*/
@Aspect //切面类需要用该注解标注
public class AspectClass {

//表达式详解需要查相关资料,这里不多说
@Pointcut("execution(* com.jzkangta.demo..*.*(..))")
/*
* 所谓切入点是指我们要对那些joinpoint进行拦截的定义
* 声明一个切入点(Pointcut),切入点是一个空的方法来声明的,后面对它的引用就用该方法名
*/
private void myPointcut() {}

/*
* 所谓通知是指拦截到joinpoint之后所要做的事情就是通知.
* 通知分为前置通知,后置通知,异常通知,最终通知,环绕通知
* 定义前置通知,可以传参数,具体请查相关资料
* myPointcut()为引用上面定义的切入点
*/
@Before("myPointcut()")
public void doAccessCheck() {
System.out.println("前置通知执行.......");
}

//后置通知,异常通知,最终通知,环绕通知,这里就不做演示
}

4.调用main方法
public static void main(String[] args) {

ApplicationContext ctx = new ClassPathXmlApplicationContext(new String[]{"beans.xml"});
PersonService personService = (PersonService) ctx.getBean("personService");
personService.save(1, "jzkangta");
}


5.beans.xml
<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xmlns:aop="http://www.springframework.org/schema/aop"
xsi:schemaLocation="http://www.springframework.org/schema/beans
http://www.springframework.org/schema/beans/spring-beans-2.5.xsd
http://www.springframework.org/schema/aop
http://www.springframework.org/schema/aop/spring-aop-2.5.xsd">

<!-- 启动对@AspectJ注解的支持 -->
<aop:aspectj-autoproxy/>
<!-- 注意personService不是一个接口 -->
<bean id="personService" class="com.jzkangta.demo.PersonService"></bean>
<!-- 将切面类也交给Spring -->
<bean id="aspectClass" class="com.jzkangta.demo.AspectClass"></bean>

</beans>


运行结果为:
前置通知执行.......
save user ----->userId=1,userName=jzkangta

二,先来基于XML声明切面
1.Person类,2.代理对象类都不用改
2.去掉了注解的切面类
package com.jzkangta.demo2;

import org.aspectj.lang.annotation.Aspect;
import org.aspectj.lang.annotation.Before;
import org.aspectj.lang.annotation.Pointcut;

/**
* 这是一个切面类
* 切面指横切性关注点的抽象即为切面,它与类相似,只是两者的关注点不一样,
* 类是对物体特征的抽象,而切面横切性关注点的抽象
* @author Administrator
*
*/
public class AspectClass {

/*
* 所谓切入点是指我们要对那些joinpoint进行拦截的定义
* 声明一个切入点(Pointcut),切入点是一个空的方法来声明的,后面对它的引用就用该方法名
*/
private void myPointcut() {}


public void doAccessCheck() {
System.out.println("前置通知执行.......");
}

//后置通知,异常通知,最终通知,环绕通知,这里就不做演示
}

3.beans.xml
<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xmlns:aop="http://www.springframework.org/schema/aop"
xsi:schemaLocation="http://www.springframework.org/schema/beans
http://www.springframework.org/schema/beans/spring-beans-2.5.xsd
http://www.springframework.org/schema/aop
http://www.springframework.org/schema/aop/spring-aop-2.5.xsd">


<!-- 注意personService不是一个接口 -->
<bean id="personService" class="com.jzkangta.demo2.PersonService"></bean>
<!-- 将切面类也交给Spring -->
<bean id="aspectClass" class="com.jzkangta.demo2.AspectClass"></bean>

<aop:config>
<aop:aspect id="myaop" ref="aspectClass">
<aop:pointcut id="mycut"
expression="execution(*com.jzkangta.demo2..*.*(..))" />
<!-- method="doAccessCheck"为切面类里的前置通知名 -->
<aop:before pointcut-ref="mycut" method="doAccessCheck" />
<!--
<aop:after-returning pointcut-ref="mycut"
method="后置通知名 " />
<aop:after-throwing pointcut-ref="mycut"
method="例外通知名" />
<aop:after pointcut-ref="mycut" method="最终通知名" />
<aop:around pointcut-ref="mycut" method="环绕的通知名" />
-->
</aop:aspect>

</aop:config>

</beans>

4.在用main方法执行后,结果如下:
前置通知执行.......
save user ----->userId=1,userName=jzkangta
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值