spring4 aop处理异常 aop的增强处理类型有哪些

Spring学习(二十五)Spring AOP之增强介绍
课程概要:
Spring AOP的基本概念Spring AOP的增强类型Spring AOP的前置增强Spring AOP的后置增强Spring AOP的环绕增强Spring AOP的异常抛出增强Spring AOP的引介增强
一.Spring AOP增强的基本概念
Spring当中的专业术语-advice,翻译成中文就是增强的意思。
所谓增强,其实就是向各个程序内部注入一些逻辑代码从而增强原有程序的功能。
二.Spring AOP的增强类型
首先先了解一下增强接口的继承关系
如上图所示:
其中带Spring标志的是Spring定义的扩展增强接口
其中带aopalliance标志的是AOP联盟所定义的接口
按照增加在目标类方法连接点的位置可以将增强划分为以下五类:
前置增强 (org.springframework.aop.BeforeAdvice) 表示在目标方法执行前来实施增强后置增强 (org.springframework.aop.AfterReturningAdvice) 表示在目标方法执行后来实施增强环绕增强 (org.aopalliance.intercept.MethodInterceptor) 表示在目标方法执行前后同时实施增强异常抛出增强 (org.springframework.aop.ThrowsAdvice) 表示在目标方法抛出异常后来实施增强引介增强 (org.springframework.aop.introductioninterceptor) 表示在目标类中添加一些新的方法和属性
其中,引介增强是一种特殊的增强。他可以在目标类中添加属性和方法,通过拦截定义一个接口,让目标代理实现这个接口。他的连接点是类级别的,而前面的几种则是方法级别的。
其中,环绕增强是AOP联盟定义的接口,其他四种增强接口则是Spring定义的接口。
其实,AOP增强很简单:
通过实现这些增强接口,在实现这些接口的方法当中定义横切逻辑,然后通过配置Spring的配置文件就可以完成将增强织入到目标方法当中了。
补充:增强既包含了横切逻辑同时又包含了部分连接点信息。
三.Spring AOP的前置增强
1.通过代码实现增强
在Spring当中,仅支持方法级别的增强,利用MethodBeforeAdvice实现,表示在目标方法执行前实施增强。
示例演示:
对服务生的服务用语进行强制规范。我们假设服务生只需要干两件事情:1.欢迎顾客 2.对顾客提供服务
那么我们创建的示例代码的主要步骤如下:
创建业务接口类:Waiter.java创建业务实现类:NativeWaiter.java创建业务增强类:GreetingBeforeAdvice.java创建增强测试类:TestAdvice.java
接下来我们分别在IDEA中创建相应的类。
服务生接口Waiter.java
public interface Waiter {
void greetTo(String name);
void serverTo(String name);
服务生实现类NativeWaiter.java
public class NativeWaiter implements Waiter{
public void greetTo(String name) {
System.out.println(&greet to&+name+&...&);
public void serverTo(String name) {
System.out.println(&serving&+name+&...&);
服务生业务增强类GreetingBeforeAdvice.java
public class GreetingBeforeAdvice implements MethodBeforeAdvice{
* 前置增强方法
* 当该方法发生异常时,将阻止目标方法的执行
* @param method 目标类方法
* @param objects 目标类方法入参
* @param o 目标类对象实例
* @throws Throwable
public void before(Method method, Object[] objects, Object o) throws Throwable {
String clientName=(String)objects[0];
System.out.println(&How Are You! mr.&+clientName);
增强测试类TestBeforeAdvice.java
public class TestBeforeAdvice {
public static void main(String[] args){
//创建目标对象
Waiter target=new NativeWaiter();
//创建增强类对象
BeforeAdvice advice=new GreetingBeforeAdvice();
//创建代理工厂对象
ProxyFactory factory=new ProxyFactory();
//设置代理类
factory.setTarget(target);
//添加增强类
factory.addAdvice(advice);
//获取代理类
Waiter proxy=(Waiter)factory.getProxy();
//调用目标类方法
proxy.greetTo(&icarus&);
proxy.serverTo(&icarus&);
程序运行结果:
How Are You! mr.icarus
greet toicarus...
How Are You! mr.icarus
servingicarus...
2.ProxyFactory介绍
其实ProxyFactory代理技术就是利用jdk代理或者cglib代理的技术,将增强应用到目标类当中。
Spring定义的AOP Proxy类具有两个final类型的实现类,如下图所示:
Cglib2AopProxy是使用cglib代理技术来创建代理
JdkDynamicAopProxy是使用jdk代理技术来创建代理
那么使用JDK代理来实现上面的代码则为:
//创建代理工厂对象
ProxyFactory factory=new ProxyFactory();
//设置代理接口
factory.setInterfaces(target.getClass().getInterfaces());
//设置代理类
factory.setTarget(target);
//设置增强类
factory.addAdvice(advice);
使用CGLib代理则为:
ProxyFactory factory=new ProxyFactory();
//设置代理接口
factory.setInterfaces(target.getClass().getInterfaces());
//启用cglib代理方式
factory.setOptimize(true);
//设置代理类
factory.setTarget(target);
//添加增强类
factory.addAdvice(advice);
可以观察到,ProxyFactory通过addAdvice来增加一个增强。
用户可以使用该方法增加多个增强,通过增强形成一个增强链,他们的调用顺序和添加顺序是一致的
3.通过配置文件实现增强
我们也可以通过配置文件来实现Spring的前置增强,并且大多数情况下都是使用配置文件方式。
首先我们介绍下ProxyFactory Bean配置文件当中常用的属性:
target:我们需要代理的目标对象proxyInterfaces:代理所要实现的接口,可以是多个接口interceptorNames:需要织入的目标对象的Bean的列表(增强类的Bean列表),使用Bean的名称来指定。singleton:确定返回的代理是不是单实例的,系统默认返回的是单实例的。optimize:当值为true时,强制使用cglib代理。当是singleton的实例时我们推荐使用cglib代理,当是其他作用域的时候,推荐使用JDK的代理。原因是cglib创建代理速度比较慢,但是运行效率高。JDK代理则刚好相反。proxyTargetClass:是否对类进行代理而不是对接口进行代理,当值为true的时候使用cglib代理
接下来我们使用配置文件对上面的示例代码进行配置:
接下来我们创建对应的测试文件
public class TestBeforeAdviceByXml {
public static void main(String[] args){
String path=&src/conf/conf-advice.xml&;
ApplicationContext context=new FileSystemXmlApplicationContext(path);
Waiter waiter=context.getBean(&waiter&,Waiter.class);
waiter.greetTo(&icarus&);
waiter.serverTo(&icarus&);
可以看到输出结果为:
How Are You! mr.icarus
greet toicarus...
How Are You! mr.icarus
servingicarus...
和我们通过代码实现增强的结果相同
四.Spring AOP的后置增强
后置增强在目标方法调用后执行,例如上面的例子中,在服务生每次服务后,也需要向客人问候,可以通过后置增强来实施这一要求,步骤如下:
创建业务接口类:Waiter.java创建业务实现类:NativeWaiter.java创建业务增强类:GreetingAfterAdvice.java创建配置文件:conf-advice.xml创建增强测试类:TestAdvice.java
接下来我们在IDEA中创建相应的代码:
我们继续使用上面的例子,由于Waiter.java和NativeWaiter.java已经创建好了
我们只需创建GreetingAfterAdvice.java
public class GreetingAfterAdvice
implements AfterReturningAdvice{
* 后置增强代码实现
* @param o 代理返回对象
* @param method 目标对象方法
* @param objects 目标对象方法参数
* @param o1 目标对象
* @throws Throwable
public void afterReturning(Object o, Method method, Object[] objects, Object o1) throws Throwable {
System.out.println(&please enjoy youself!&);
接下来我们修改对应的配置文件
首先得将后者增强类作为bean配置到文件当中
接下来得在ProxyFactory Bean当中添加织入的bean
p:interceptorNames=&gerrtingBefore,gerrtingAfter&
完整的配置文件如下:
测试文件和上面的保持不变,运行测试类,测试结果为:
How Are You! mr.icarus
greet toicarus...
please enjoy youself!
How Are You! mr.icarus
servingicarus...
please enjoy youself!
五.Spring AOP的环绕增强
环绕增强允许在目标类方法调用前后织入横切逻辑,它综合实现了前置,后置增强两者的功能,下面是我们用环绕增强同时实现上面的我们的示例。步骤如下:
创建业务接口类:Waiter.java创建业务实现类:NativeWaiter.java创建业务增强类:GreetingInterceptor.java创建配置文件:conf-advice.xml创建增强测试类:TestAdvice.java
接下来我们在IDEA中来实现。
首先创建GreetingInterceptor.java
public class GreetingInterceptor implements MethodInterceptor{
* 业务逻辑实现类
* @param methodInvocation 封装了目标方法和入参数组以及目标方法所带的实例对象
* @return 代理对象
* @throws Throwable
public Object invoke(MethodInvocation methodInvocation) throws Throwable {
//获取目标方法的入参
Object[] args=methodInvocation.getArguments();
//获取方法名称
String clickName= (String) args[0];
System.out.println(&GreetingInterceptor:How are you!&);
//利用反射机制来调用目标方法
Object object=methodInvocation.proceed();
System.out.println(&GreetingInterceptor: please enjoy youself!&);
接下来在配置文件中对其进行配置:
启动测试类,观察打印结果:
How Are You! mr.icarus
GreetingInterceptor:How are you!
greet toicarus...
GreetingInterceptor: please enjoy youself!
please enjoy youself!
How Are You! mr.icarus
GreetingInterceptor:How are you!
servingicarus...
GreetingInterceptor: please enjoy youself!
please enjoy youself!
可以看到,我们成功在示例中实现了前置增强,后者增强以及环绕增强。
六.Spring AOP的异常抛出增强
异常抛出增强表示在目标方法抛出异常后实施增强,最适合的场景是事务管理,比如当参与事事务的方法抛出异常后需要回滚事务。
异常抛出增强类需要实现ThrowsAdvice接口,ThrowsAdvice接口并没有定义任何的方法,他只是一个标志接口。
在运行期,Spring采用反射的机制来进行判断。我们必须采用以下的形式来定义异常抛出的方法
public void afterThrowing(Method method,Object[] args,Object target,Throwable t)
方法名必须为afterThrowing,方法入参中前三个入参是可选的,即要么同时存在,要么都没有
最后一个入参是Throwable及其子类,必须得有。
也可以在异常增强类中定义多个方法,Spring会自动选择匹配的方法来进行调用。
在类的继承树上,两个类的距离越近,则两个类的相似度越高
那么当方法抛出异常时,会优先选取异常入参和抛出的异常相似度最高的afterThrowing方法。
接下来我们创建示例来演示一下,步骤如下:
创建业务实现类:ForumService.java创建业务增强类:TransactionManager.java创建配置文件:conf-advice.xml创建增强测试类:TestAdvice.java
接下来我们在IDEA上分别创建对应的代码:
首先,我们创建业务逻辑类ForumService
public class ForumService {
public void removeForum(){
//进行相应的操作,但这里只为演示抛出异常
throw new RuntimeException(&removeForum:Exception...&);
public void updateForum(){
//进行相应的数据库操作,但这里只为演示抛出异常
throw new RuntimeException(&updateForum:Exception...&);
接下来我们创建增强类TransactionManager
public class TransactionManager implements ThrowsAdvice{
* 捕获异常并打印异常名称
* @param method 目标对象对应方法
* @param args 方法入参
* @param target 目标对象
* @param ex 运行方法所捕获的异常
* @throws Throwable
public void afterThrowing(Method method,Object[] args,Object target,Exception ex)throws Throwable{
System.out.println(&method:&+method.getName());
System.out.println(&抛出异常:&+ex.getMessage());
System.out.println(&成功回滚事务&);
接下来我们编写对应的配置文件
创建相应的测试类进行测试
public static void testThrowAdvice(){
String path=&src/conf/conf-advice.xml&;
ApplicationContext context=new FileSystemXmlApplicationContext(path);
ForumService forumService=context.getBean(&forumService&,ForumService.class);
forumService.removeForum();
}catch (Exception e){}
forumService.updateForum();
}catch (Exception e){}
运行结果为:
method:removeForum
抛出异常:removeForum:Exception...
成功回滚事务
method:updateForum
抛出异常:updateForum:Exception...
成功回滚事务
七.Spring AOP的引介增强
引介增强是一种比较特殊的增强类型,他不是在目标方法周围织入增强,而是为目标创建新的方法和属性,所以他的连接点是类级别的而非方法级别的。通过引介增强我们可以为目标类添加一个接口的实现即原来目标类未实现某个接口,那么通过引介增强可以为目标类创建实现某接口的代理。
接下来我们创建一个示例来演示下,步骤如下:
创建接口类:Monitorable.java创建业务类:PerformanceMonitor.java创建增强类:ControllablePerformanceMonitor.java创建配置文件:conf-advice-introduce.xml创建增强测试类:TestIntroduce.java
接下来我们在IDEA上分别创建对应的代码:
首先创建性能监视接口Monitorable
public interface Monitorable {
void setMonitorActive(boolean active);
创建测试接口Testable
public interface Testable {
void test();
接下来创建业务类
public class PerformanceMonitor {
private static ThreadLocal performaceRecord = new ThreadLocal();
public static void begin(String method) {
System.out.println(&begin monitor...&);
MethodPerformace mp = performaceRecord.get();
if(mp == null){
mp = new MethodPerformace(method);
performaceRecord.set(mp);
mp.reset(method);
public static void end() {
System.out.println(&end monitor...&);
MethodPerformace mp = performaceRecord.get();
mp.printPerformace();
接下来创建增强类ControllablePerformanceMonitor
public class ControllablePerformaceMonitor
DelegatingIntroductionInterceptor implements Monitorable, Testable {
private ThreadLocal MonitorStatusMap = new ThreadLocal();
public void setMonitorActive(boolean active) {
MonitorStatusMap.set(active);
public Object invoke(MethodInvocation mi) throws Throwable {
Object obj =
if (MonitorStatusMap.get() != null && MonitorStatusMap.get()) {
PerformanceMonitor.begin(mi.getClass().getName() + &.&
+ mi.getMethod().getName());
obj = super.invoke(mi);
PerformanceMonitor.end();
obj = super.invoke(mi);
public void test() {
// TODO Auto-generated method stub
System.out.println(&dd&);
接下来创建所要增强的方法类
public class ForumService {
public void removeTopic(int topicId) {
System.out.println(&模拟删除Topic记录:&+topicId);
Thread.currentThread().sleep(20);
} catch (Exception e) {
throw new RuntimeException(e);
public void removeForum(int forumId) {
System.out.println(&模拟删除Forum记录:&+forumId);
Thread.currentThread().sleep(40);
} catch (Exception e) {
throw new RuntimeException(e);
public class MethodPerformace {
private String serviceM
public MethodPerformace(String serviceMethod){
reset(serviceMethod);
public void printPerformace(){
end = System.currentTimeMillis();
long elapse = end -
System.out.println(serviceMethod+&花费&+elapse+&毫秒。&);
public void reset(String serviceMethod){
this.serviceMethod = serviceM
this.begin = System.currentTimeMillis();
创建配置文件来将所设置的代码组合起来:
创建对应的测试类
public class TestIntroduce {
public static void main(String[] args) {
testBeforeAdviceByCode();
private static void testBeforeAdviceByCode() {
String configPath = &src/conf/conf-advice-introduce.xml&;
ApplicationContext ctx = new FileSystemXmlApplicationContext(configPath);
ForumService forumService = (ForumService)ctx.getBean(&forumService&);
forumService.removeForum(10);
forumService.removeTopic(1022);
Monitorable moniterable = (Monitorable)forumS
moniterable.setMonitorActive(true);
forumService.removeForum(10);
forumService.removeTopic(1022);
程序运行结果为:
模拟删除Forum记录:10
模拟删除Topic记录:1022
begin monitor...
模拟删除Forum记录:10
end monitor...
org.springframework.aop.framework.CglibAopProxy$CglibMethodInvocation.removeForum花费40毫秒。
begin monitor...
模拟删除Topic记录:1022
end monitor...
org.springframework.aop.framework.CglibAopProxy$CglibMethodInvocation.removeTopic花费20毫秒。
增强其实就是对原有的方法或类动态增加功能,可为方法执行前后以及所抛出的异常进行逻辑处理。实现增强的方式有两种:代码方式和XML配置文件方式,建议在以后开发中使用后者,这样可以避免代码的耦合度,方便后期维护。
(window.slotbydup=window.slotbydup || []).push({
id: '2467140',
container: s,
size: '1000,90',
display: 'inlay-fix'
(window.slotbydup=window.slotbydup || []).push({
id: '2467141',
container: s,
size: '1000,90',
display: 'inlay-fix'
(window.slotbydup=window.slotbydup || []).push({
id: '2467143',
container: s,
size: '1000,90',
display: 'inlay-fix'
(window.slotbydup=window.slotbydup || []).push({
id: '2467148',
container: s,
size: '1000,90',
display: 'inlay-fix'<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN"
您的访问请求被拒绝 403 Forbidden - ITeye技术社区
您的访问请求被拒绝
亲爱的会员,您的IP地址所在网段被ITeye拒绝服务,这可能是以下两种情况导致:
一、您所在的网段内有网络爬虫大量抓取ITeye网页,为保证其他人流畅的访问ITeye,该网段被ITeye拒绝
二、您通过某个代理服务器访问ITeye网站,该代理服务器被网络爬虫利用,大量抓取ITeye网页
请您点击按钮解除封锁&Spring三种事宜处理方式_基于spring aop 权限管理系统原形_基础知识的温习__脚本百事通
稍等,加载中……
^_^请注意,有可能下面的2篇文章才是您想要的内容:
Spring三种事宜处理方式
基于spring aop 权限管理系统原形
基础知识的温习
Spring三种事宜处理方式
Spring三种事务处理方式1、用原始的transactionfactorybean的,代理dao事务处理
2、用aop:config声明要进行事务增强的切面,用tx:advice声明具体方法的事务属性,及应用到的事务管理器
3、使用@transactional注解配置声明事务(最简单实用的方法)
如有一代表用户的域对象user:package com.import java.io.public class user implements serializable{private int user_private string user_private string user_private string user_....//省略set、get方法}
user的数据库操作接口:package com.import com.domain.public interface userdao {public void adduser(user user);}
有一继承spring jdbc支持类的userdao接口实现类,实现添加一个user的方法。它需要注入一个spring jdbc模板类jdbctemplate:package com.dao.import com.domain.import com.dao.import org.springframework.jdbc.core.support.
public class userjdbcdao extends jdbcdaosupport implements userdao{public void adduser(user user){string sql = "insert into user(user_name,user_password,user_desc) values(?,?,?)";object[] params = new object[]{user.getuser_name(),user.getuser_password(),user.getuser_desc()} ;this.getjdbctemplate().update(sql, params);}}
以上dao层的类对应的bean的基本配置文件app_dao.xml如下(数据源的属性放入了外部的资源文件"prop.properties"):
&bean class="org.springframework.beans.factory.config.propertyplaceholderconfigurer"&&property name="location" value="classpath:prop.properties"/&&/bean&&!--数据源--&&bean id="datasource" class="mons.dbcp.basicdatasource"destroy-method="close"&&property name="driverclassname" value="${jdbc.driverclassname}"/&&property name="url" value="${jdbc.url}"/&&property name="username" value="${jdbc.username}"/&&property name="password" value="${jdbc.password}"/&&/bean&&!--spring jdbc模板bean,它注入了上面的数据源--&&bean id="jdbctemplate" class="org.springframework.jdbc.core.jdbctemplate"&&property name="datasource" ref="datasource"/&&/bean&
&!--user数据操作的bean声明,它注入了上面的spring jdbc模板bean:jdbctemplate--&&bean id="userjdbcdao"class="com.dao.jdbc.userjdbcdao"&&property name="jdbctemplate" ref="jdbctemplate"/& &/bean&&/beans&
这里我简单地模拟业务类(业务接口userservice省略):package com.service.import com.dao.import com.domain.import com.service.
public class userserviceimpl implements userservice {pripublic void setuserdao(userdao userdao){this.userdao =}public void adduser(user user){this.userdao.adduser(user);}}
为了在业务类中使用事务管理功能,有如下几个方法:1、用原始的transactionfactorybean的app.xml基本配置:
&import resource="classpath:app_dao.xml"/&&!--导入dao层的配置--&&!--spring jdbc的事务管理bean,引入了dbcp数据源--&&bean id="txmanager" class="org.springframework.jdbc.datasource.datasourcetransactionmanager"&&property name="datasource" ref="datasource"/&&/bean&&!--业务类bean--&&bean id="userserviceimpltarget" class="com.service.impl.userserviceimpl"&&property name="userdao" ref="userjdbcdao"/&&/bean&
&!--应用原始的transactionfactorybean进行事务管理bean的声明--&&bean id="userserviceimpl"class="org.springframework.transaction.interceptor.transactionproxyfactorybean"&&property name="transactionmanager" ref="txmanager"/&&!--指定事务管理bean--&&property name="target" ref="userserviceimpltarget"/&&!--指定业务bean--&&property name="transactionattributes"&&!--事务的属性设置列表--&&props&&prop key="add*"&propagation_required,isolation_serializable&/prop&&!--设置事务为只读时,添加数据将会产生异常--&&!--&prop key="add*"&propagation_required,isolation_serializable,readonly&/prop&--&&/props&&/property&&/bean&
测试:......userserviceimpl usi = (userserviceimpl)ctx.getbean("userserviceimpl");......
2、用tx/aop命名空间配置:
&?xml version="1.0" encoding="utf-8"?&&beans .....xmlns:tx="http://www.springframework.org/schema/tx"xsp:schemalocation="http://www.springframework.org/schema/beans...........http://www.springframework.org/schema/txhttp://www.springframework.org/schema/tx/spring-tx-2.0.xsd"&
&import resource="classpath:app_dao.xml"/&
&bean id="txmanager" class="org.springframework.jdbc.datasource.datasourcetransactionmanager"&&property name="datasource" ref="datasource"/&&/bean&
&bean id="userserviceimpltarget" class="com.service.impl.userserviceimpl"&&property name="userdao" ref="userjdbcdao"/&&/bean&
&!--应用tx/aop命名空间进行事务声明--&&!--用tx:advice声明具体方法的事务属性,及应用到的事务管理器--&&tx:advice id="txadvice" transaction-manager="txmanager"&&tx:attributes&&tx:method name="add*" read-only="true"/&&/tx:attributes&&/tx:advice&&!--用aop:config声明要进行事务增强的切面--&&aop:config&&aop:pointcut id="servicemethod"expression="execution(* com.service..add*(..))"/&&aop:advisor pointcut-ref="servicemethod" advice-ref="txadvice"/&&/aop:config&&/beans&
测试:.......userservice usi = (userservice)ctx.getbean("userserviceimpltarget");..........
3、使用@transactional注解配置声明事务(最简单实用的方法):
在需要事务管理增强的业务类加入@transactional注解标记,如:......import org.springframework.transaction.annotation. //注解式事务
@transactional(readonly=false) //对业务类进行事务增强的标注public class userserviceimpl implements userservice {...........}
再在配置文件中用&tx:annotation-driven&驱动自动为标记@transactional注解的类织入事务管理增强:&import resource="classpath:app_dao.xml"/&
&bean id="txmanager" class="org.springframework.jdbc.datasource.datasourcetransactionmanager"&&property name="datasource" ref="datasource"/&&/bean&
&!--注解式事务配置驱动--&&tx:annotation-driven transaction-manager="txmanager" proxy-target-class="true"/&
&!--业务类bean的实现类标注了@transactional注解,所以会被tx:annotation-driven注解驱动自动织入事务增强--&&bean id="userservice" class="com.service.impl.userserviceimpl"&&property name="userdao" ref="userjdbcdao"/&&/bean&
测试:.........userserviceimpl usi = (userserviceimpl)ctx.getbean("userservice");.........
基于spring aop 权限管理系统原形
基于spring aop 权限管理系统原型
此权限管理系统把待访问的业务层方法做为权限管理中的资源,通过spring aop 对接口方法进行拦截,来实现权限的管理,可以实现细粒度的权限控制。在上文体验了spring aop 一些特性,aop 接口:MethodBeforeAdvice, AfterReturningAdvice, ThrowsAdvice 实现这三个接口分别对方法执行前,后,执行中抛异常等情况进行的,我们要是想做overload 这样的操作时,要用MethodInterceptor 接口,此接口好在有返回值,public Object invoke(
MethodInvocation invocation)
throws Throwable
{//.}上文做法有些牵强业务逻辑还有throws PermissionDeniedException 感觉不爽,现在用MethodInterceptor 接口,来写这个demo,把权限与业务分开。advice 如下:public class PermissionCheckAroundAdvice implements MethodInterceptor {
SecurityManager securityMgr = new SecurityManager();
* @param securityMgr The securityMgr to set.
public void setSecurityMgr(SecurityManager securityMgr) {
this.securityMgr = securityM
public Object invoke(MethodInvocation invocation) throws Throwable {
System.out.println("(被调用方法接口类名: "
+ invocation.getMethod().getDeclaringClass().getName() + ")");
System.out.println("(被调用方法名:" + invocation.getMethod().getName()+ ")");
String methodName = invocation.getMethod().getDeclaringClass()
.getName() + "." + invocation.getMethod().getName();
System.out.println("(被调用方法全名:" + methodName + ")");
System.out.println("有否权限:(" + securityMgr.checkPermission(methodName)+ ")");
if(securityMgr.checkPermission(methodName))
return invocation.proceed();
System.out.println("Goodbye! NO Permission!(by " + this.getClass().getName() + ")");
return "--";
}}服务层业务接口修改如下:public interface Service {
public String getBeanInfo();}服务层业务实现类如下:public class ServiceBean implements Service {
* @param bean The bean to set.
public void setBean(ResourceBean bean) {
this.bean =
public String getBeanInfo(){
String result="";
result+= bean.getMethod1();
result+= bean.getMethod2();
result+= bean.getMethod3();
}}资源层,接口 ,类如下:public interface Resource {}public interface ResourceBean extends Resource{
public void theMethod();
public String getMethod1();
public String getMethod2();
public String getMethod3();}public class ResourceBeanImpl implements ResourceBean,InitializingBean{
public void theMethod(){
System.out.println(this.getClass().getName()
+ "." + new Exception().getStackTrace()[0].getMethodName()
+ " says HELLO!");
public String getMethod1(){
return "张三";
public String getMethod2(){
return "李四";
public String getMethod3(){
return "王五";
public void afterPropertiesSet() throws Exception {
System.out.println("事件监听:类ResourceBeanImpl属性设置完毕");
}}权限管理类:public class User {
List privilages = new java.util.ArrayList();
public User(){
* @param privilages The privilages to set.
public void setPrivilages(List privilages) {
this.privilages =
public String getName(){
public void setName(String name){
this.name=
public boolean isPermission(String pri){
java.util.Iterator it = privilages.iterator();
String p = "";
boolean pass=
while(it.hasNext()){
p=(String)it.next();
System.out.println(p);
if(p.equals(pri)){
}}public class SecurityManager {
public void setUser(User user){
this.user =
public boolean checkPermission(String privilege){
return checkPermission(user,privilege);
public boolean checkPermission(User user, String privilege){
return user.isPermission(privilege);
}}配置文件:&?xml version="1.0" encoding="UTF-8"?&&!DOCTYPE beans PUBLIC
"-//SPRING//DTD BEAN//EN" "http://www.springframework.org/dtd/spring-beans.dtd"&&beans&
&!--CONFIG--&
&bean id="bean" class="org.springframework.aop.framework.ProxyFactoryBean"&
&property name="proxyInterfaces"&
&value&com.jhalo.jsecurity.aop.ResourceBean&/value&
&/property&
&property name="target"&
&ref local="beanTarget"/&
&/property&
&property name="interceptorNames"&
&value&permissionAroundAdvisor&/value&
&/property&
&bean id="service" class="org.springframework.aop.framework.ProxyFactoryBean"&
&property name="proxyInterfaces"&
&value&com.jhalo.jsecurity.aop.Service&/value&
&/property&
&property name="target"&
&ref local="serviceBean"/&
&/property&
&property name="interceptorNames"&
&value&permissionAroundAdvisor&/value&
&/property&
&!--CLASS--&
&bean id="resourceMgr" class="com.jhalo.jsecurity.aop.ResourceManager"/&
&bean id="beanTarget" class="com.jhalo.jsecurity.aop.ResourceBeanImpl"/&
&bean id="beanTarget2" class="com.jhalo.jsecurity.aop.ResourceBean2Impl"/&
&bean id="user" class="com.jhalo.jsecurity.aop.User"&
&property name="name"&
&value&tester&/value&
&/property&
&property name="privilages"&
&value&com.jhalo.jsecurity.aop.ResourceBean.getMethod3&/value&
&value&com.jhalo.jsecurity.aop.Service.getBeanInfo&/value&
&value&com.jhalo.jsecurity.aop.ResourceBean.getMethod1&/value&
&/property&
&bean id="securityMgr" class="com.jhalo.jsecurity.aop.SecurityManager"&
&property name="user"&
&ref local="user"/&
&/property&
&bean id="serviceBean" class="com.jhalo.jsecurity.aop.ServiceBean"&
&property name="bean"&
&!-- &ref local="beanTarget"/&--&
&ref local="bean"/&
&/property&
&!--ADVISOR--&
&!--Note: An advisor assembles pointcut and advice--&
&!-- permission around advisor --&
&bean id="permissionAroundAdvisor" class="org.springframework.aop.support.RegexpMethodPointcutAdvisor"&
&property name="advice"&
&ref local="thePermissionAroundAdvice"/&
&/property&
&property name="pattern"&
&value&.*&/value&
&/property&
&!--ADVICE--&
&bean id="thePermissionCheckBeforeAdvice" class="com.jhalo.jsecurity.aop.PermissionCheckAdvice"/&
&bean id="thePermissionThrowsAdvice" class="com.jhalo.jsecurity.aop.PermissionThrowsAdvice"/&
&bean id="thePermissionAroundAdvice" class="com.jhalo.jsecurity.aop.PermissionCheckAroundAdvice"&
&property name="securityMgr"&
&ref local="securityMgr"/&
&/property&
&/bean&&/beans&User 所拥有的权限是在spring 配置文件中手工配置的,在实际应用中不可行,可以从DB中取得。测试类:public class SpringAopTest {
public static void main(String[] args) {
//Read the configuration file
ApplicationContext ctx
= new FileSystemXmlApplicationContext("springconfig.xml");String name = "";Service sb = (Service)ctx.getBean("service");//
System.out.println("---"+ctx.isSingleton("service")+"---");
name = sb.getBeanInfo();
System.out.println("test result::" +name);
基础知识的温习
基础知识的复习1. SAN
 SAN(Storage Area Network的简称)直译过来就是存储区域网络,它采用光纤通道(Fibre Channel)技术,通过光纤通道交换机连接存储阵列和服务器主机,建立专用于数据存储的区域网络。SAN网络存储是一种高速网络或子网络,SAN存储系统提供在计算机与存储系统之间的数据传输。
NAS存储网络
NAS是通过网线连接的磁盘阵列,具备磁盘阵列的所有主要特征:高容量、高效能、高可靠。
这是一种直接与主机系统相连接的存储设备,如作为服务器的计算机内部硬件驱动。
2.硬中断和软中断
编程异常通常叫做软中断 软中断是通讯进程之间用来模拟硬中断的一种信号通讯方式。 中断源发中段请求或软中断信号后,CPU
或接收进程在适当的时机自动进行中断处理或完成软中断信号对应的功能。
硬中断是硬件实现的中断,是程序运行时设备对它的中断
3.简述ISO OSI的物理层Layer1,链路层Layer2,网络层Layer3的任务。
网络层:资料传送的目的地寻址,再选择出传送资料的最佳路线;链路层:负责网络上资料封包如何传送的方式;物理层:在设备与传输媒介之间建立及终止连接。参与通讯过程使得资源可以在共享的多用户中有效分配,对信号进行调制或转换使得用户设备中的数字信号定义能与信道上实际传送的数字信号相匹配
网络层为建立网络连接和为上层提供服务,应具备以下主要功能.
① 路由选择和中继.
② 激活,终止网络连接.
③ 在一条数据链路上复用多条网络连接,多采取分时复用技术.
④ 差错检测与恢复.
⑤ 排序,流量控制.
⑥ 服务选择.
⑦ 网络管理.
4.什么是进程和线程?有何区别?线程是进程的一个实体,是CPU调度和分派的基本单位,它是比进程更小的能独立运行的基本单位.线程自己基本上不拥有系统资源,只拥有一点在运行中必不可少的资源(如程序计数器,一组寄存器和栈),但是它可与同属一个进程的其他的线程共享进程所拥有的全部资源.一个线程可以创建和撤销另一个线程;同一个进程中的多个线程之间可以并发执行.
TCP/IP四层模型和OSI七层模型
表1-1是 TCP/IP四层模型和OSI七层模型对应表。我们把OSI七层网络模型和Linux TCP/IP四层概念模型对应,然后将各种网络协议归类。
TCP/IP四层模型和OSI七层模型对应表
OSI七层网络模型
Linux TCP/IP四层概念模型
对应网络协议
应用层(Application)
TFTP, FTP, NFS, WAIS
表示层(Presentation)
Telnet, Rlogin, SNMP, Gopher
会话层(Session)
传输层(Transport)
网络层(Network)
IP, ICMP, ARP, RARP, AKP, UUCP
数据链路层(Data Link)
FDDI, Ethernet, Arpanet, PDN, SLIP, PPP
物理层(Physical)
IEEE 802.1A, IEEE 802.2到IEEE 802.11
6. 面向连接(TCP)的套接字的系统调用时序图。
AS: socket()建立流式套接字,返回套接字号SS。
↓BS: bind(),套接字SS与本地地址相连。
↓CS: listen(),通知TCP服务器准备好接受连接。
↓DS: accpet(),接受连接等待客户端的连接。
AC: socket()建立流式套接字号SC。
↓ES: 建立连接,accpet()返回得到新的套接字,如NS。
BC: connection(),将套接字S与远地主机连接。
&------------------ Connect to ES_FS
↓FS: recv() & send(),在套接字NS上读写数据直到完成交换。
CC: send() & recv(),在套接字上读写数据直到数据交换完成。
↓GS: closesocket(), 关闭套接字NS。
DC: closesocket(),关闭套接字SC,结束TCP对话。
Goto: C to D
↓HS: closesocket(),关闭最初套接字SS,服务结束。
8.New delete 与malloc free 的联系与区别?
答案:都是在堆(heap)上进行动态的内存操作。用malloc函数需要指定内存分配的字节数并且不能初始化对象,new 会自动调用对象的构造函数。delete 会调用对象的destructor,而free 不会调用对象的destructor.
9.观察者模式的缺点
(1) 如果一个被观察者对象有很多直接和间接的观察者的话,将所有的观察者都通知到会花费很多时间。
(2)如果在被观察者之间有循环依赖的话, 被观察者会触发它们之间进行循环调用,导致系统崩溃。在使用观察考模式时要特别注意这一点。
(3)如果对观察者的通知是通过另外的线程进 行异步投递的话,系统必须保证投递是以自恰(?)的方式进行的。
(4)虽然观察者模式可以随时使观察者知道所观察的对象发生了变化,但是观察者 模式没有相应的机制使观察者知道所观察的对象是怎么发生变化的。
如果您想提高自己的技术水平,欢迎加入本站官方1号QQ群:&&,&&2号QQ群:,在群里结识技术精英和交流技术^_^
本站联系邮箱:

我要回帖

更多关于 spring aop通知类型 的文章

 

随机推荐