马士兵Spring-AOP-Aspect例子使用(1)
一、例子1:
1.工程结构:
2.
User.java:
package com.cy.model; public class User {
private String username;
private String password;
public String getUsername() {
return username;
}
public void setUsername(String username) {
this.username = username;
}
public String getPassword() {
return password;
}
public void setPassword(String password) {
this.password = password;
}
}
UserDAO.java:
package com.cy.dao; import com.cy.model.User; public interface UserDAO {
public void save(User user);
}
UserDAOImpl.java:
package com.cy.dao.impl; import org.springframework.stereotype.Component; import com.cy.dao.UserDAO;
import com.cy.model.User; @Component
public class UserDAOImpl implements UserDAO { public void save(User user) {
//Hibernate
//JDBC
//XML
//NetWork
System.out.println("user saved!");
//throw new RuntimeException("exeption!");
} }
UserService.java:
package com.cy.service; import javax.annotation.Resource; import org.springframework.stereotype.Component; import com.cy.dao.UserDAO;
import com.cy.model.User; @Component("userService")
public class UserService { @Resource
private UserDAO userDAO; public void init() {
System.out.println("init");
} public void add(User user) {
userDAO.save(user);
} public UserDAO getUserDAO() {
return userDAO;
} public void setUserDAO( UserDAO userDAO) {
this.userDAO = userDAO;
} public void destroy() {
System.out.println("destroy");
}
}
LogInterceptor.java:
package com.cy.aop; import org.aspectj.lang.annotation.Aspect;
import org.aspectj.lang.annotation.Before;
import org.springframework.stereotype.Component; @Aspect
@Component
public class LogInterceptor { /**
* execution 专门的方法的切入语法;
* 可以很方便的指定加到哪个/哪些方法上;
* execution: 方法的执行;UserDAOImpl.save方法执行的时候;
* UserDAOImpl.save方法一执行,先把下面的方法before()加到前面 @Before
*/
@Before("execution(public void com.cy.dao.impl.UserDAOImpl.save(com.cy.model.User))")
public void before() {
System.out.println("method before");
}
}
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:context="http://www.springframework.org/schema/context"
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/context
http://www.springframework.org/schema/context/spring-context-2.5.xsd
http://www.springframework.org/schema/aop
http://www.springframework.org/schema/aop/spring-aop-2.5.xsd"> <context:annotation-config />
<context:component-scan base-package="com.cy"/> <!-- 在spring容器的初始化过程中,会将com.cy下面的所有类都会扫描,
扫描的时候发现@Component,将这个类初始化;
同时发现@Aspect,发现这是一个切面逻辑,可以把它切到其他类的方法上面去;
发现@Befored定义了下;在执行execution中的方法前面加入逻辑
-->
<aop:aspectj-autoproxy /> </beans>
测试代码:
UserServiceTest.java:
package com.cy.service; import org.junit.Test;
import org.springframework.context.support.ClassPathXmlApplicationContext; import com.cy.model.User; public class UserServiceTest { @Test
public void testAdd() throws Exception {
ClassPathXmlApplicationContext ctx = new ClassPathXmlApplicationContext("beans.xml");
UserService service = (UserService)ctx.getBean("userService");
System.out.println(service.getClass());
service.add(new User());
ctx.destroy();
}
}
运行结果:
一些概念:
二、例子2:
1.一些织入点语法:
1.the execution of any public method:
execution(public * *(..))
第1个* 任何返回值:
第2个* *(..)任何类的任何方法 2.the execution of any method with a name beginning with "set":
execution(* set*(..))
set*(..) 以set开头的任何方法 3.the execution of any method defined by the AccountService interface:
execution(* com.xyz.service.AccountService.*(..))
任何返回值;
com.xyz.service.AccountService类下面的任何方法; 4.the execution of any method defined in the service package:
execution(* com.xyz.service.*.*(..)) 5.the execution of any method defined in the service package or a sub-package:
execution(* com.xyz.service..*.*(..))
com.xyz.service下面的包,子包,不管子包多少层;里面的任何类任何方法; 6.any join point (method execution only in Spring AOP) within the service package:
within(com.xyz.service.*)
method execution only in Spring AOP spring自身也实现了一套AOP的语法;它也支持使用Aspect的语法来实现;
大部分情况下用不到spring自身的AOP;
2.各种各样类型的Advice:
1.Before advice 2.After returning advice
After returning advice runs when a matched method execution returns normally. It is declared using the @AfterReturning annotation:
只要这个方法正常执行完了,会执行我们的AfterReturning
如:
@AfterReturning("com.xyz.myapp.SystemArchitecture.dataAccessOperation()")
public void doAccessCheck() {
// ...
} 3.After throwing advice
After throwing advice runs when a matched method execution exits by throwing an exception. It is declared using the @AfterThrowing annotation:
当一个方法执行抛出异常的时候,抛出了任何异常,就会执行@AfterThrowing
如:
@AfterThrowing("com.xyz.myapp.SystemArchitecture.dataAccessOperation()")
public void doRecoveryActions() {
// ...
} 4.After (finally) advice
执行你的方法时候是写try catch finally;catch到异常的时候是执行@AfterThrowing;最后一定会执行finally; 5.Around advice
around环绕;前面可以加逻辑,后面也可以加逻辑;
如:
import org.aspectj.lang.annotation.Aspect;
import org.aspectj.lang.annotation.Around;
import org.aspectj.lang.ProceedingJoinPoint;
@Aspect
public class AroundExample { @Around("com.xyz.myapp.SystemArchitecture.businessService()")
public Object doBasicProfiling(ProceedingJoinPoint pjp) throws Throwable {
// start stopwatch 加了自己的逻辑;
Object retVal = pjp.proceed(); //想让程序继续执行,必须调pjp.proceed(),程序才会继续运行;可以参考责任链设计模式;
//struts2的Interceptor也是这么用的;
// stop stopwatch 后面加自己的逻辑
return retVal;
}
}
使用例子1:
LogInterceptor.java:
package com.cy.aop; import org.aspectj.lang.annotation.AfterReturning;
import org.aspectj.lang.annotation.Aspect;
import org.aspectj.lang.annotation.Before;
import org.springframework.stereotype.Component; @Aspect
@Component
public class LogInterceptor { /**
* execution 方法运行
* com.cy.dao下面包括它的子包下面,任何类的任何方法;返回值任何类型
*/
@Before("execution(public * com.cy.dao..*.*(..))")
public void before() {
System.out.println("method before");
} /**
* @AfterReturning 方法正常执行完成之后
*
*/
@AfterReturning("execution(public * com.cy.dao..*.*(..))")
public void afterReturning() {
System.out.println("method after returning");
} }
运行UserServiceTest.java:--- console:
使用例子2:afterThrowing:
LogInterceptor.java:
package com.cy.aop; 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;
import org.springframework.stereotype.Component; @Aspect
@Component
public class LogInterceptor { @Before("execution(public * com.cy.dao..*.*(..))")
public void before() {
System.out.println("method before");
} @AfterThrowing("execution(public * com.cy.dao..*.*(..))")
public void afterThrowing() {
System.out.println("method after throwing");
} }
UserDAOImpl.java中手动抛出一个异常:
@Component
public class UserDAOImpl implements UserDAO { public void save(User user) {
//Hibernate
//JDBC
//XML
//NetWork
System.out.println("user saved!");
throw new RuntimeException("exeption!");
} }
console:
使用例子3:@Around:
LogInterceptor.java:
package com.cy.aop; import org.aspectj.lang.ProceedingJoinPoint;
import org.aspectj.lang.annotation.AfterReturning;
import org.aspectj.lang.annotation.AfterThrowing;
import org.aspectj.lang.annotation.Around;
import org.aspectj.lang.annotation.Aspect;
import org.aspectj.lang.annotation.Before;
import org.aspectj.lang.annotation.Pointcut;
import org.springframework.stereotype.Component; @Aspect
@Component
public class LogInterceptor { @Before("execution(public * com.cy.dao..*.*(..))")
public void before() {
System.out.println("method before");
} @Around("execution(public * com.cy.dao..*.*(..))")
public void aroundMethod(ProceedingJoinPoint pjp) throws Throwable {
System.out.println("method around start");
pjp.proceed();
System.out.println("method around end");
} }
console:
使用例子4:
把切点定义到UserService.java中的add方法上:
LogInterceptor.java:
package com.cy.aop; import org.aspectj.lang.ProceedingJoinPoint;
import org.aspectj.lang.annotation.AfterReturning;
import org.aspectj.lang.annotation.AfterThrowing;
import org.aspectj.lang.annotation.Around;
import org.aspectj.lang.annotation.Aspect;
import org.aspectj.lang.annotation.Before;
import org.aspectj.lang.annotation.Pointcut;
import org.springframework.stereotype.Component; @Aspect
@Component
public class LogInterceptor { @Before("execution(public * com.cy.service..*.add(..))")
public void before() {
System.out.println("method before");
} @Around("execution(public * com.cy.dao..*.*(..))")
public void aroundMethod(ProceedingJoinPoint pjp) throws Throwable {
System.out.println("method around start");
pjp.proceed();
System.out.println("method around end");
} }
运行junit但是报错了:
org.springframework.beans.factory.BeanCreationException: Error creating bean with name 'userService' defined in file [E:\jdbcWorkspace\spring_aop\bin\com\cy\service\UserService.class]: Initialization of bean failed; nested exception is org.springframework.aop.framework.AopConfigException: Cannot proxy target class because CGLIB2 is not available. Add CGLIB to the class path or specify proxy interfaces.


马士兵Spring-AOP-Aspect例子使用(1)的更多相关文章
- Spring aop 小例子demo
由于最近的服务项目提供接口有一个需求,所有操作都必须检查操作的服务可用,所以感觉Aop特别适合实施.完成学习的小例子. 关于spring-Aop原理:http://m.oschina.net/blog ...
- 马士兵 spring 视频笔记
课程内容 1. 面向接口(抽象)编程的概念与好处 2. IOC/DI的概念与好处 a) inversion of control b) dependen ...
- Spring AOP 学习例子
http://outofmemory.cn/code-snippet/3762/Spring-AOP-learn-example 工作忙,时间紧,不过事情再多,学习是必须的.记得以前的部门老大 ...
- Spring AOP @Aspect
spring提供了两个核心功能,一个是IoC(控制反转),另外一个便是Aop(面向切面编程),IoC有助于应用对象之间的解耦,AOP则可以实现横切关注点(如日志.安全.缓存和事务管理)与他们所影响的对 ...
- Spring AOP(aspect oriented programming) 转载
1.面向切面的基本原理 软件系统可以看成是由一组关注点组成的,其中,直接的业务关注点,是直切关注点.而为直切关注点提供服务的,就是横切关注点. 01.什么是面向切面编程 横切关注点:影响应用多处的功能 ...
- Spring AOP Aspect的简单实现(基于XML)
第一步:导包 第二步:实现类和切面类 Service("userService")public class IUserviceImpl implements IUserServic ...
- Spring AOP Aspect的简单实现(基于注解)
第1步:声明使用注解 <!-- 配置扫描注解--> 扫描包的位置<context:component-scan base-package="com.zz"/> ...
- Spring AOP实战例子与springmvc整合不起效果的解决办法
在使用AOP之前,首先我们先了解一下什么是AOP吧.在网上很多人将AOP翻译为“面向切面编程”,什么是面向切面?与面向对象有什么区别呢? 在回答这两个问题之前,我们先要明白切面的概念. 切面由切点与增 ...
- [Spring] AOP, Aspect实例解析
最近要用到切面来统一处理日志记录,写了个小实例练了练手: 具体实现类: public interface PersonServer { public void save(String name); p ...
- c# spring aop的简单例子
刚刚完成了一个c#的spring aop简单例子,是在mac下用Xamarin Studio开发的.代码如下: 接口 using System; using System.Collections.Ge ...
随机推荐
- SDOI2011_染色
SDOI_染色 背景:很早就想学习树链剖分,趁着最近有点自由安排的时间去学习一下,发现有个很重要的前置知识--线段树.(其实不一定是线段树,但是线段树应该是最常见的),和同学吐槽说树剖的剖和分都很死板 ...
- SDN前瞻 传统网络架构的危机:危机“四”起
本文基于SDN导论的视频而成:SDN导论 在网络发展速度如此之快的今天,传统网络的架构充满了危机,主要有这四个问题(3+1). 1)传统网络的部署和管理 非常困难 2)分布式网络架构凸显瓶颈 3)流量 ...
- ZOJ 3769 Diablo III(分组背包)
http://acm.zju.edu.cn/onlinejudge/showProblem.do?problemCode=3769 题意:有13种装备,每种装备值可以穿戴一种,特殊的就是双手武器和单手 ...
- 线程池ThreadPoolExecutor里面4种拒绝策略
ThreadPoolExecutor类实现了ExecutorService接口和Executor接口,可以设置线程池corePoolSize,最大线程池大小,AliveTime,拒绝策略等.常用构造方 ...
- 在 R 中使用 Python 字符串函数
sprintf( )函数很强大,但并非适用于所有应用场景.例如,如果一些部分在模板中多次出现,那么就需要多次写一样的参数.这通常会使得代码冗长而且难以修改:sprintf("%s, %d y ...
- 雷林鹏分享:Ruby 迭代器
Ruby 迭代器 迭代器是集合支持的方法.存储一组数据成员的对象称为集合.在 Ruby 中,数组和散列可以称之为集合. 迭代器返回集合的所有元素,一个接着一个.在这里我们将讨论两种迭代器,each 和 ...
- python开发_sqlite3_绝对完整_博主推荐
'''SQLite数据库是一款非常小巧的嵌入式开源数据库软件,也就是说 没有独立的维护进程,所有的维护都来自于程序本身. 在python中,使用sqlite3创建数据库的连接,当我们指定的数据库文件不 ...
- Linux网络编程--洪水攻击详解
洪水攻击详解 ①注解:洪水攻击(FLOOD ATTACK)是指利用计算机网络技术向目标主机发送大量无用的数据报文,使得目标主机忙于处理无用的数据报文而无法提供正常服务的网络行为. 主要原理:利用了网络 ...
- Presto改造
最近在打造一款可视化分析产品, 需要用到组合多数据源, 进行查询, 看了挺多开源的插件, 发现目前只有Presto比较符合, 但是由于Presto没有多用户机制和资源管理, 所以需要在这基本上构建多用 ...
- IOS-网络(数据安全:MD5加密)
// // ViewController.m // IOS_0129_HTTP请求 // // Created by ma c on 16/1/29. // Copyright © 2016年 博文科 ...