Spring02-AOP
1,动态代理,指的是通过一个代理对象创建需要的业务对象,然后在这个代理对象中统一进行各种操作。
步骤:
1)写一个类实现InvocationHandler接口;
2)创建要代理的对象
2,创建一个简单的打印日志的类Logger
package com.yangw.spring.proxy;
import java.util.Date;
public class Logger {
public static void info(String msg){
System.out.println(new Date()+"----"+msg);
}
}
3,自定义注解类
package com.yangw.spring.model;
import java.lang.annotation.Retention;
import java.lang.annotation.RetentionPolicy;
@Retention(RetentionPolicy.RUNTIME)
public @interface LogInfo {
public String value() default "";
}
4,自定义动态代理类LogProxy
package com.yangw.spring.proxy;
import java.lang.reflect.InvocationHandler;
import java.lang.reflect.Method;
import java.lang.reflect.Proxy;
import com.yangw.spring.model.LogInfo;
/**
* 1 写一个类,实现InvocationHandler接口
* @author Administrator
*
*/
public class LogProxy implements InvocationHandler {
//2,创建代理对象
private Object target;
private LogProxy(){};
//3,创建一个方法来生成代理对象,这个方法的参数是要代理的对象
public static Object getInstance(Object obj){
//3.1 创建LogProxy对象
LogProxy proxy=new LogProxy();
//3.2 设置代理对象
proxy.target=obj;
//3.3 通过Proxy.newProxyInstance()创建代理对象
//参数1:要代理对象的classloader,参数2:要代理对象的实现的所有接口,
//参数3:实现InvocationHandler接口的对象
return Proxy.newProxyInstance(obj.getClass().getClassLoader(),
obj.getClass().getInterfaces(), proxy);
}
/**
* 当有了代理对象之后,都会调用下面的invoke()方法
*/
@Override
public Object invoke(Object proxy, Method method, Object[] args)
throws Throwable {
//这里怎么处理完全由我们来控制的
/*if(method.getName().equals("add")|| method.getName().equals("delete")){
Logger.info("调用我...");
}*/
//只对有LogInfo注解的进行处理,
//而且是在method.invoke调用之前,调用之后执行都可以
//在异常中进行处理也可以
if(method.isAnnotationPresent(LogInfo.class)){
Logger.info(method.getAnnotation(LogInfo.class).value());
}
return method.invoke(target, args);
//aspect orient program (面向切面编程)
}
}
5,在需要加入注解的接口上面加入自定义注解LogInfo
package com.yangw.spring.dao;
import com.yangw.spring.model.LogInfo;
import com.yangw.spring.model.User;
public interface IUserDao {
@LogInfo("add a user")
public void add(User user) ;
@LogInfo("delete a user")
public void delete(int id) ;
public User load(int id);
}
6,beans2.xml中的配置如下
<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"
xsi:schemaLocation="http://www.springframework.org/schema/beans
http://www.springframework.org/schema/beans/spring-beans-3.0.xsd
http://www.springframework.org/schema/context
http://www.springframework.org/schema/context/spring-context-3.0.xsd">
<!--1, 打开Spring的annotation -->
<context:annotation-config/>
<!-- 2, 设定Spring去那些包中找annotation -->
<context:component-scan base-package="com.yangw.spring" />
<!--用代理类实现
对于静态(static)的注入,使用factory-method
-->
<bean id="userDynamicDao" class="com.yangw.spring.proxy.LogProxy"
factory-method="getInstance">
<!--静态方法传入的参数 -->
<constructor-arg ref="userDao" />
</bean>
<!-- 依次加入想加入的
<bean id="msgDynamicDao" class="com.yangw.spring.proxy.LogProxy"
factory-method="getInstance">
<constructor-arg ref="MsgDao" />
</bean>
-->
</beans>
7,UserService类上注入userDynamicDao
package com.yangw.spring.service;
import javax.annotation.Resource;
import org.springframework.stereotype.Service;
import com.yangw.spring.dao.IUserDao;
import com.yangw.spring.model.User;
@Service("userService")
public class UserService implements IUserService {
@Resource(name="userDynamicDao")
private IUserDao userDao ;
@Override
public void add(User user) {
userDao.add(user);
}
@Override
public void delete(int id) {
userDao.delete(id);
}
@Override
public User load(int id) {
return userDao.load(id);
}
}
7, 测试
package com.yangw.spring.test;
import org.junit.Test;
import org.springframework.beans.factory.BeanFactory;
import org.springframework.context.support.ClassPathXmlApplicationContext;
import com.yangw.spring.action.UserAction;
import com.yangw.spring.model.User;
public class TestSpring {
//1,创建Spring工厂
BeanFactory factory= new ClassPathXmlApplicationContext("beans2.xml");
@Test
public void testUser(){
//2,通过工厂获取Spring的对象
UserAction userAction = factory.getBean("userAction", UserAction.class);
User u1=new User(1,"yangw");
userAction.setUser(u1);
userAction.add();
userAction.delete();
userAction.load();
}
}
8, Spring实现动态代理(基于annotation方式)
导入aopalliance-1.0.jar aspectjrt-1.6.10.jar aspectjweaver-1.7.2.jar 三个包,Spring使用这三个包实现AOP
<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-3.0.xsd
http://www.springframework.org/schema/context
http://www.springframework.org/schema/context/spring-context-3.0.xsd
http://www.springframework.org/schema/aop
http://www.springframework.org/schema/aop/spring-aop.xsd">
<!--1, 打开Spring的annotation -->
<context:annotation-config/>
<!-- 2, 设定Spring去那些包中找annotation -->
<context:component-scan base-package="com.yangw.spring" />
<!-- 打开基于annotation的aop自动代理 -->
<aop:aspectj-autoproxy />
</beans>
切面类
package com.yangw.spring.proxy;
import org.aspectj.lang.JoinPoint;
import org.aspectj.lang.ProceedingJoinPoint;
import org.aspectj.lang.annotation.After;
import org.aspectj.lang.annotation.Around;
import org.aspectj.lang.annotation.Aspect;
import org.aspectj.lang.annotation.Before;
import org.springframework.stereotype.Component;
@Component("logAspect") //交给Spring管理
@Aspect //说明是一个切面类
public class LogAspect {
//前置通知
// 第1个"*": 任意返回值
// 第2个"*": com.yangw.spring.dao包中的所有类
// 第3个"*": add*表示以add开头的所有方法
// "(..)" : 表示方法参数是任意值
// "||" : 可以用或表达式加入多个条件
/**
* 函数调用之前执行
*/
@Before("execution(* com.yangw.spring.dao.*.add*(..))||"
+"execution(* com.yangw.spring.dao.*.delete*(..))||"
+"execution(* com.yangw.spring.dao.*.update*(..))")
public void logStart(JoinPoint jp){
System.out.println(jp.getTarget()); //得到执行的类
System.out.println(jp.getSignature().getName()); //得到执行的方法名
Logger.info("log start.");
}
/**
* 函数调用之后执行
*/
@After("execution(* com.yangw.spring.dao.*.add*(..))||"
+"execution(* com.yangw.spring.dao.*.delete*(..))||"
+"execution(* com.yangw.spring.dao.*.update*(..))")
public void logEnd(JoinPoint jp){
System.out.println(jp.getTarget()); //得到执行的类
System.out.println(jp.getSignature().getName()); //得到执行的方法名
Logger.info("log end.");
}
/**
* 函数调用过程中执行
*/
@Around("execution(* com.yangw.spring.dao.*.add*(..))||"
+"execution(* com.yangw.spring.dao.*.delete*(..))||"
+"execution(* com.yangw.spring.dao.*.update*(..))")
public void logAround(ProceedingJoinPoint pjp) throws Throwable{
Logger.info("log around start");
pjp.proceed(); //让程序往下执行
Logger.info("log around end.");
}
}
测试
package com.yangw.spring.test;
import org.junit.Test;
import org.springframework.beans.factory.BeanFactory;
import org.springframework.context.support.ClassPathXmlApplicationContext;
import com.yangw.spring.action.UserAction;
import com.yangw.spring.model.User;
public class TestSpring {
//1,创建Spring工厂
BeanFactory factory= new ClassPathXmlApplicationContext("beans3.xml");
@Test
public void testUser(){
//2,通过工厂获取Spring的对象
UserAction userAction = factory.getBean("userAction", UserAction.class);
User u1=new User(1,"yangw");
userAction.setUser(u1);
userAction.add();
userAction.delete();
userAction.load();
}
}
测试结果
Mon Oct 21 19:13:29 CST 2013----log around start com.yangw.spring.dao.UserDao@18ce14a add Mon Oct 21 19:13:29 CST 2013----log start. add :User [id=1, username=yangw] Mon Oct 21 19:13:29 CST 2013----log around end. com.yangw.spring.dao.UserDao@18ce14a add Mon Oct 21 19:13:29 CST 2013----log end. Mon Oct 21 19:13:29 CST 2013----log around start com.yangw.spring.dao.UserDao@18ce14a delete Mon Oct 21 19:13:29 CST 2013----log start. delete :0 Mon Oct 21 19:13:29 CST 2013----log around end. com.yangw.spring.dao.UserDao@18ce14a delete Mon Oct 21 19:13:29 CST 2013----log end. load :0 null
9, Spring实现动态代理(基于xml方式) 一般这种用的多
导入aopalliance-1.0.jar aspectjrt-1.6.10.jar aspectjweaver-1.7.2.jar 三个包,Spring使用这三个包实现AOP
<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-3.0.xsd
http://www.springframework.org/schema/context
http://www.springframework.org/schema/context/spring-context-3.0.xsd
http://www.springframework.org/schema/aop
http://www.springframework.org/schema/aop/spring-aop.xsd">
<!--1, 打开Spring的annotation -->
<context:annotation-config/>
<!-- 2, 设定Spring去那些包中找annotation -->
<context:component-scan base-package="com.yangw.spring" />
<aop:config>
<!-- 定义切面 -->
<aop:aspect id="myLogAspect" ref="logAspect">
<!-- 在哪些位置加入相应的Aspect-->
<aop:pointcut id="logPointCut" expression="execution(* com.yangw.spring.dao.*.add*(..))||
execution(* com.yangw.spring.dao.*.delete*(..))||
execution(* com.yangw.spring.dao.*.update*(..))" />
<!-- 定义通知 -->
<aop:before method="logStart" pointcut-ref="logPointCut"/>
<aop:after method="logEnd" pointcut-ref="logPointCut"/>
<aop:around method="logAround" pointcut-ref="logPointCut"/>
</aop:aspect>
</aop:config>
</beans>
package com.yangw.spring.proxy;
import org.aspectj.lang.JoinPoint;
import org.aspectj.lang.ProceedingJoinPoint;
import org.springframework.stereotype.Component;
@Component("logAspect") //交给Spring管理
public class LogAspect1 {
public void logStart(JoinPoint jp){
System.out.println(jp.getTarget()); //得到执行的类
System.out.println(jp.getSignature().getName()); //得到执行的方法名
Logger.info("log start.");
}
public void logEnd(JoinPoint jp){
System.out.println(jp.getTarget()); //得到执行的类
System.out.println(jp.getSignature().getName()); //得到执行的方法名
Logger.info("log end.");
}
public void logAround(ProceedingJoinPoint pjp) throws Throwable{
Logger.info("log around start");
pjp.proceed(); //让程序往下执行
Logger.info("log around end.");
}
}
测试和结果与前面的基于annotation的一模一样,不在赘述!
Spring02-AOP的更多相关文章
- JAVAEE——spring02:使用注解配置spring、sts插件、junit整合测试和aop演示
一.使用注解配置spring 1.步骤 1.1 导包4+2+spring-aop 1.2 为主配置文件引入新的命名空间(约束) 1.3 开启使用注解代替配置文件 1.4 在类中使用注解完成配置 2.将 ...
- Spring第二天——IOC注解操作与AOP概念
大致内容 spring的bean管理(注解实现) AOP原理 log4j介绍 spring整合web项目的演示 一.spring注解实现bean管理 注解: 代码中一些特殊的标记,使用注解也可以完成一 ...
- spring-02
spring-02 1.谈谈你对 Spring 的理解 Spring 是一个开源框架,为简化企业级应用开发而生.Spring 可以是使简单的 JavaBean 实现以前只有 EJB 才能实现的功能.S ...
- Spring03——有关于 Spring AOP 的总结
本文将为各位带来 Spring 的另一个重点知识点 -- Spring AOP.关注我的公众号「Java面典」,每天 10:24 和你一起了解更多 Java 相关知识点. 什么是 AOP 面向切面编程 ...
- 基于spring注解AOP的异常处理
一.前言 项目刚刚开发的时候,并没有做好充足的准备.开发到一定程度的时候才会想到还有一些问题没有解决.就比如今天我要说的一个问题:异常的处理.写程序的时候一般都会通过try...catch...fin ...
- Spring基于AOP的事务管理
Spring基于AOP的事务管理 事务 事务是一系列动作,这一系列动作综合在一起组成一个完整的工作单元,如果有任何一个动作执行失败,那么事务 ...
- 学习AOP之透过Spring的Ioc理解Advisor
花了几天时间来学习Spring,突然明白一个问题,就是看书不能让人理解Spring,一方面要结合使用场景,另一方面要阅读源代码,这种方式理解起来事半功倍.那看书有什么用呢?主要还是扩展视野,毕竟书是别 ...
- 学习AOP之深入一点Spring Aop
上一篇<学习AOP之认识一下SpringAOP>中大体的了解了代理.动态代理及SpringAop的知识.因为写的篇幅长了点所以还是再写一篇吧.接下来开始深入一点Spring aop的一些实 ...
- 学习AOP之认识一下Spring AOP
心碎之事 要说知道AOP这个词倒是很久很久以前了,但是直到今天我也不敢说非常的理解它,其中的各种概念即抽象又太拗口. 在几次面试中都被问及AOP,但是真的没有答上来,或者都在面上,这给面试官的感觉就是 ...
- .Net中的AOP系列之构建一个汽车租赁应用
返回<.Net中的AOP>系列学习总目录 本篇目录 开始一个新项目 没有AOP的生活 变更的代价 使用AOP重构 本系列的源码本人已托管于Coding上:点击查看. 本系列的实验环境:VS ...
随机推荐
- 神经网络与深度学习笔记 Chapter 3.
交叉熵 交叉熵是用于解决使用二次代价函数时当单个神经元接近饱和的时候对权重和bias权重学习的影响.这个公式可以看出,当神经元饱和的时候,sigma的偏导接近于0,w的学习也会变小.但是应用交叉熵作为 ...
- 一起来学Go --- (go的变量)
变量 变量是几乎所有编程语言中最基本的组成元素,从根本上说,变量相当于是一块数据存储空间的命名,程序可以通过定义一个变量来申请一块数据存储空间,之后可以通过引用变量名来使用这块存储空间.go语言中的变 ...
- 一道风骚的DP
也是校赛学长出的一道题~想穿了很简单..但我还是听了学长讲才明白. 观察力有待提高. Problem D: YaoBIG's extra homeworkTime LimitMemory Limit1 ...
- JavaWeb(九)AJAX
Ajax ajax:AJAX 是与服务器交换数据的艺术,它在不重载全部页面的情况下,实现了对部分网页的更新 AJAX:Asynchronous JavaScript and XML,异步 javasc ...
- 调试大叔V1.0.1(2017.09.01)|http/s接口调试、数据分析程序员辅助开发神器
2017.09.01 - 调试大叔 V1.0.1*支持http/https协议的get/post调试与反馈:*可保存请求协议的记录:*内置一批动态参数,可应用于URL.页头.参数:*可自由管理cook ...
- [知了堂学习笔记]_纯JS制作《飞机大战》游戏_第3讲(逻辑方法的实现)
整体展示: 上一讲实现了诸多对象,这次我们就需要实现许多逻辑方法,如控制飞机移动,判断子弹击中敌机,敌机与英雄飞机相撞等等.并且我们在实现这些功能的时候需要计时器去调用这些方法.setInterval ...
- 第一篇--认识Jmeter
Jmeter是Apache组织开发的基于Java的压力测试工具,它最初被设计用于Web应用测试,但后来扩展到其他测试领域. 它可以用于测试静态和动态资源,例如静态文件.Java 小服务程序.CGI 脚 ...
- Android检查更新下载安装
检查更新是任何app都会用到功能,任何一个app都不可能第一个版本就能把所有的需求都能实现,通过不断的挖掘需求迭代才能使app变的越来越好.检查更新自动下载安装分以下几个步骤: 请求服务器判断是否有最 ...
- Wireshark使用drcom_2011.lua插件协助分析drcom协议
drcom_2011.lua是来源于Google code上的一个开源项目中的一个插件,感谢网络大神的分享 需要使用drcom_2011.lua分析drcom协议的话,需要把drcom_2011.lu ...
- HTTP协议是无状态协议,怎么理解
详见:http://blog.yemou.net/article/query/info/tytfjhfascvhzxcytp24 HTTP协议是无状态协议,怎么理解? 2010-02-23 09:4 ...