- 浏览: 21434062 次
- 性别:
博客专栏
-
跟我学spring3
浏览量:2404982
-
Spring杂谈
浏览量:2997639
-
跟开涛学SpringMVC...
浏览量:5631433
-
Servlet3.1规范翻...
浏览量:257561
-
springmvc杂谈
浏览量:1593147
-
hibernate杂谈
浏览量:248965
-
跟我学Shiro
浏览量:5847500
-
跟我学Nginx+Lua开...
浏览量:698136
-
亿级流量网站架构核心技术
浏览量:780438
文章分类
- 全部博客 (329)
- 跟我学Nginx+Lua开发 (13)
- 跟我学spring (54)
- 跟开涛学SpringMVC (34)
- spring4 (16)
- spring杂谈 (50)
- springmvc杂谈 (22)
- 跟我学Shiro (26)
- shiro杂谈 (3)
- hibernate杂谈 (10)
- java开发常见问题分析 (36)
- 加速Java应用开发 (5)
- Servlet 3.1规范[翻译] (21)
- servlet3.x (2)
- websocket协议[翻译] (14)
- websocket规范[翻译] (1)
- java web (6)
- db (1)
- js & jquery & bootstrap (4)
- 非技术 (4)
- reminder[转载] (23)
- 跟叶子学把妹 (8)
- nginx (2)
- 架构 (19)
- flume架构与源码分析 (4)
最新评论
-
xxx不是你可以惹得:
认真看错误代码,有时候重启电脑就行了 醉了 我把数据库配置写死 ...
第十六章 综合实例——《跟我学Shiro》 -
dagger9527:
holyselina 写道您前面说到能获取调用是的参数数组,我 ...
【第六章】 AOP 之 6.6 通知参数 ——跟我学spring3 -
xxx不是你可以惹得:
Access denied for user 'root'@' ...
第十六章 综合实例——《跟我学Shiro》 -
dagger9527:
只有@AspectJ支持命名切入点,而Schema风格不支持命 ...
【第六章】 AOP 之 6.5 AspectJ切入点语法详解 ——跟我学spring3 -
dagger9527:
支持虽然会迟到,但永远不会缺席!
【第四章】 资源 之 4.3 访问Resource ——跟我学spring3
我对SpringDAO层支持的总结
- 博客分类:
- spring杂谈
之前发过两篇关于Spring的总结帖子 反响还不错,再把剩下的几篇发上来。共享给大家。
我对IoC/DI的理解
我对AOP的理解
1、问题
1、JDBC/ORM框架(如Hibernate)开发中编程模型有哪些缺点? 如JDBC
2、解决方案(模板设计模式,本质:将可变的和不可变的分离)
模板方法模式:定义操作的步骤(固定的),将可变的步骤交给子类处理。
public interface JdbcOperations { //接口定义行为集 public Object execute() throws SQLException ; }
public abstract class AbstractJdbcOperations implements JdbcOperations { @Override public final Object execute() throws SQLException { Connection conn = DataSourceUtils.getConnection(); try { Object retVal = doInConnection(conn); conn.commit(); return retVal; }catch (Exception e) { conn.rollback(); throw e;} finally { conn.close(); } } public abstract Object doInConnection(Connection conn) throws SQLException; }
public class DataSourceUtils { public static Connection getConnection() { //返回数据库连接 return null; } }
JdbcOperations select = new AbstractJdbcOperations() { @Override public Object doInConnection(Connection conn) throws SQLException { PreparedStatement pstmt = conn.prepareStatement("select * from tbl_user"); ResultSet rs = pstmt.executeQuery(); List result = null; //处理结果集 return result; } }; select.execute();
缺点:不够灵活
3、解决方案(模板设计模式+回调,本质:将可变的和不可变的分离,可变通过回调)
回调(命令):由组件定义,但不由组件调用,而是由系统调用
一般用于:可变不可变分离,未知功能。
public interface JdbcOprations2 { //接口定义行为集 public Object execute(ConnectionCallback callback) throws Exception ; }
public interface ConnectionCallback { public Object doInConnection(Connection conn) throws SQLException; }
public class JdbcTemplate implements JdbcOprations2 { @Override public Object execute(ConnectionCallback callback) throws Exception { Connection conn = DataSourceUtils.getConnection(); try { Object retVal = callback.doInConnection(conn); conn.commit(); return retVal; } catch (Exception e) { conn.rollback(); throw e; } finally { conn.close(); } } }
jdbcTemplate.execute(new ConnectionCallback() { @Override public Object doInConnection(Connection conn) throws SQLException { //可变操作 return null; } });
public interface PreparedStatementCallback { public Object doInPreparedStatement(PreparedStatement pstmt) throws SQLException; }缺点:灵活但不通用
4、解决方案(Spring JDBC框架)
JdbcTemplate jdbcTemplate = new JdbcTemplate(ds);
5、异常问题
JDBC/ORM框架(如Hibernate)开发中异常处理有哪些缺点? 不一致的异常类,如JDBC是SQLException 而hibernate是HibernateException,等。
缺点:不一致的异常体系,需要了解每个框架的异常含义 ,Spring的一致的异常体系(DataAccessException)
6、DAO访问问题
访问JDBC和访问Hibernate使用完全不同且根本不类似的API?
为了便于以一种一致的方式使用各种数据访问技术,如JDBC、JDO和Hibernate,
Spring提供了一套抽象DAO类供你扩展。
JdbcDaoSupport - JDBC数据访问对象的基类。
需要一个DataSource,同时为子类提供 JdbcTemplate。
HibernateDaoSupport - Hibernate数据访问对象的基类。
需要一个SessionFactory,同时为子类提供 HibernateTemplate。
JdoDaoSupport - JDO数据访问对象的基类。
需要设置一个PersistenceManagerFactory, 同时为子类提供JdoTemplate。
JpaDaoSupport - JPA数据访问对象的基类。
需要一个EntityManagerFactory,同时 为子类提供JpaTemplate。
一致的DAO抽象
Callback:定义可变行为,即不可预知行为(命令设计模式)
Template:提供模板支持,简化开发Support:提供对Template的支持,提供一组简便方法,并提供获取Template的方法
相关资料
评论
10 楼
jinnianshilongnian
2012-12-06
9 楼
yangpeihai
2012-12-06
yangpeihai 写道
jinnianshilongnian 写道
yangpeihai 写道
哥们,请教个问题,为什么spring使用cglib动态代理没法拦截被代理类的所有非private方法,而我自己写的由cglib生成的代理类却可以拦截到被代理类的所有非private方法呢?,先道声谢谢,下面贴代码:
1. 注解类,用来注解哪些方法需要写日志
2. 工厂类,由cglib生成被代理对象
3.被代理的类
4.测试类
5.结果输出:
[12/06 14:47:52] [DEBUG] ProxyFactory: Method: public java.lang.String test.log.Student.doWork1(java.lang.String,int)
[12/06 14:47:52] [DEBUG] ProxyFactory: params: ["Xiao Zhang",22]
[12/06 14:47:52] [DEBUG] ProxyFactory: Method: java.lang.String test.log.Student.doWork2(java.lang.String,int)
[12/06 14:47:52] [DEBUG] ProxyFactory: params: ["Xiao Zhang",22]
[12/06 14:47:52] [DEBUG] ProxyFactory: Method: protected java.lang.String test.log.Student.doWork3(java.lang.String,int)
[12/06 14:47:52] [DEBUG] ProxyFactory: params: ["Xiao Zhang",22]
[12/06 14:47:52] [DEBUG] ProxyFactory: result:"姓名: Xiao Zhang, 年龄: 22"
[12/06 14:47:52] [DEBUG] ProxyFactory: result:"姓名: Xiao Zhang, 年龄: 22"
[12/06 14:47:52] [DEBUG] ProxyFactory: result:"姓名: Xiao Zhang, 年龄: 22"
如果把被代理类放到spring里面,则只能拦截到方法doWork1,其他方法拦截不到,为什么会有这种差异?
1. 注解类,用来注解哪些方法需要写日志
@Target(ElementType.METHOD) @Retention(RetentionPolicy.RUNTIME) @Documented public @interface MyLog { }
2. 工厂类,由cglib生成被代理对象
public class ProxyFactory { private final static Callback DEFAULT_CALLBACK = new DefaultCallback(); private final static Log log = LogFactory.getLog(ProxyFactory.class); public static <T> T newInstance(Class<T> clazz) { return newInstance(clazz, DEFAULT_CALLBACK); } @SuppressWarnings("unchecked") public static <T> T newInstance(Class<T> clazz, Callback callback) { Enhancer enhancer = new Enhancer(); enhancer.setSuperclass(clazz); enhancer.setCallback(callback); return (T) enhancer.create(); } private static class DefaultCallback implements MethodInterceptor { @Override public Object intercept(Object obj, Method method, Object[] args, MethodProxy proxy) throws Throwable { Object result = null; //只有标志了MyLog的方法才写日志 boolean flag = method.isAnnotationPresent(MyLog.class); if(flag){ log.debug("Method: " + method.toGenericString()); log.debug("params: " + JSON.toJSONString(args)); } // 调用方法 result = proxy.invokeSuper(obj, args); if(flag){ log.debug("result:" + JSON.toJSONString(result)); } return result; } } }
3.被代理的类
public class Student { public Student() { } public static Student newProxyInstance() { return ProxyFactory.newInstance(Student.class); } @MyLog public String doWork1(String name, int age) { return doWork2(name,age); } @MyLog String doWork2(String name, int age) { return doWork3(name,age); } @MyLog protected String doWork3(String name, int age) { return doWork4(name,age); } @MyLog private String doWork4(String name, int age) { return "姓名: " + name + ", 年龄: " + age; } }
4.测试类
public class Test { public static void main(String[] args) { Student stu = Student.newProxyInstance(); stu.doWork1("Xiao Zhang", 22); } }
5.结果输出:
[12/06 14:47:52] [DEBUG] ProxyFactory: Method: public java.lang.String test.log.Student.doWork1(java.lang.String,int)
[12/06 14:47:52] [DEBUG] ProxyFactory: params: ["Xiao Zhang",22]
[12/06 14:47:52] [DEBUG] ProxyFactory: Method: java.lang.String test.log.Student.doWork2(java.lang.String,int)
[12/06 14:47:52] [DEBUG] ProxyFactory: params: ["Xiao Zhang",22]
[12/06 14:47:52] [DEBUG] ProxyFactory: Method: protected java.lang.String test.log.Student.doWork3(java.lang.String,int)
[12/06 14:47:52] [DEBUG] ProxyFactory: params: ["Xiao Zhang",22]
[12/06 14:47:52] [DEBUG] ProxyFactory: result:"姓名: Xiao Zhang, 年龄: 22"
[12/06 14:47:52] [DEBUG] ProxyFactory: result:"姓名: Xiao Zhang, 年龄: 22"
[12/06 14:47:52] [DEBUG] ProxyFactory: result:"姓名: Xiao Zhang, 年龄: 22"
如果把被代理类放到spring里面,则只能拦截到方法doWork1,其他方法拦截不到,为什么会有这种差异?
spring内部实现的问题
可以看看我之前回复的
http://www.iteye.com/topic/1125911#2368327
回答神速啊,拜读啦。。。
里面有个问题,他那个setSelf(ServiceA self)是怎么注入的
public void setSelf(ServiceA self) { this.self = self; }
我在我自己的Service直接用@Autowired报错,代码片段如下
public class UserService extends BaseService{ private UserService self; @Autowired public void setSelf(UserService self) { this.self = self; }
没找到匹配类型!错误信息:
org.springframework.beans.factory.BeanCreationException: Error creating bean with name 'studentController': Injection of autowired dependencies failed; nested exception is org.springframework.beans.factory.BeanCreationException: Could not autowire field: private com.oy.service.UserService com.oy.controller.StudentController.userService; nested exception is org.springframework.beans.factory.BeanCreationException: Error creating bean with name 'userService': Injection of autowired dependencies failed; nested exception is org.springframework.beans.factory.BeanCreationException: Could not autowire method: public void com.oy.service.UserService.setSelf(com.oy.service.UserService); nested exception is org.springframework.beans.factory.NoSuchBeanDefinitionException: No matching bean of type [com.oy.service.UserService] found for dependency: expected at least 1 bean which qualifies as autowire candidate for this dependency. Dependency annotations: {}
at org.springframework.beans.factory.annotation.AutowiredAnnotationBeanPostProcessor.postProcessPropertyValues(AutowiredAnnotationBeanPostProcessor.java:285)
at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.populateBean(AbstractAutowireCapableBeanFactory.java:1074)
at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.doCreateBean(AbstractAutowireCapableBeanFactory.java:517)
at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.createBean(AbstractAutowireCapableBeanFactory.java:456)
其实我要说的意思是这里的setSelf是类,而不是接口,这样可以吗?我尝试了,如果是类会报错,接口没问题。
8 楼
yangpeihai
2012-12-06
jinnianshilongnian 写道
yangpeihai 写道
哥们,请教个问题,为什么spring使用cglib动态代理没法拦截被代理类的所有非private方法,而我自己写的由cglib生成的代理类却可以拦截到被代理类的所有非private方法呢?,先道声谢谢,下面贴代码:
1. 注解类,用来注解哪些方法需要写日志
2. 工厂类,由cglib生成被代理对象
3.被代理的类
4.测试类
5.结果输出:
[12/06 14:47:52] [DEBUG] ProxyFactory: Method: public java.lang.String test.log.Student.doWork1(java.lang.String,int)
[12/06 14:47:52] [DEBUG] ProxyFactory: params: ["Xiao Zhang",22]
[12/06 14:47:52] [DEBUG] ProxyFactory: Method: java.lang.String test.log.Student.doWork2(java.lang.String,int)
[12/06 14:47:52] [DEBUG] ProxyFactory: params: ["Xiao Zhang",22]
[12/06 14:47:52] [DEBUG] ProxyFactory: Method: protected java.lang.String test.log.Student.doWork3(java.lang.String,int)
[12/06 14:47:52] [DEBUG] ProxyFactory: params: ["Xiao Zhang",22]
[12/06 14:47:52] [DEBUG] ProxyFactory: result:"姓名: Xiao Zhang, 年龄: 22"
[12/06 14:47:52] [DEBUG] ProxyFactory: result:"姓名: Xiao Zhang, 年龄: 22"
[12/06 14:47:52] [DEBUG] ProxyFactory: result:"姓名: Xiao Zhang, 年龄: 22"
如果把被代理类放到spring里面,则只能拦截到方法doWork1,其他方法拦截不到,为什么会有这种差异?
1. 注解类,用来注解哪些方法需要写日志
@Target(ElementType.METHOD) @Retention(RetentionPolicy.RUNTIME) @Documented public @interface MyLog { }
2. 工厂类,由cglib生成被代理对象
public class ProxyFactory { private final static Callback DEFAULT_CALLBACK = new DefaultCallback(); private final static Log log = LogFactory.getLog(ProxyFactory.class); public static <T> T newInstance(Class<T> clazz) { return newInstance(clazz, DEFAULT_CALLBACK); } @SuppressWarnings("unchecked") public static <T> T newInstance(Class<T> clazz, Callback callback) { Enhancer enhancer = new Enhancer(); enhancer.setSuperclass(clazz); enhancer.setCallback(callback); return (T) enhancer.create(); } private static class DefaultCallback implements MethodInterceptor { @Override public Object intercept(Object obj, Method method, Object[] args, MethodProxy proxy) throws Throwable { Object result = null; //只有标志了MyLog的方法才写日志 boolean flag = method.isAnnotationPresent(MyLog.class); if(flag){ log.debug("Method: " + method.toGenericString()); log.debug("params: " + JSON.toJSONString(args)); } // 调用方法 result = proxy.invokeSuper(obj, args); if(flag){ log.debug("result:" + JSON.toJSONString(result)); } return result; } } }
3.被代理的类
public class Student { public Student() { } public static Student newProxyInstance() { return ProxyFactory.newInstance(Student.class); } @MyLog public String doWork1(String name, int age) { return doWork2(name,age); } @MyLog String doWork2(String name, int age) { return doWork3(name,age); } @MyLog protected String doWork3(String name, int age) { return doWork4(name,age); } @MyLog private String doWork4(String name, int age) { return "姓名: " + name + ", 年龄: " + age; } }
4.测试类
public class Test { public static void main(String[] args) { Student stu = Student.newProxyInstance(); stu.doWork1("Xiao Zhang", 22); } }
5.结果输出:
[12/06 14:47:52] [DEBUG] ProxyFactory: Method: public java.lang.String test.log.Student.doWork1(java.lang.String,int)
[12/06 14:47:52] [DEBUG] ProxyFactory: params: ["Xiao Zhang",22]
[12/06 14:47:52] [DEBUG] ProxyFactory: Method: java.lang.String test.log.Student.doWork2(java.lang.String,int)
[12/06 14:47:52] [DEBUG] ProxyFactory: params: ["Xiao Zhang",22]
[12/06 14:47:52] [DEBUG] ProxyFactory: Method: protected java.lang.String test.log.Student.doWork3(java.lang.String,int)
[12/06 14:47:52] [DEBUG] ProxyFactory: params: ["Xiao Zhang",22]
[12/06 14:47:52] [DEBUG] ProxyFactory: result:"姓名: Xiao Zhang, 年龄: 22"
[12/06 14:47:52] [DEBUG] ProxyFactory: result:"姓名: Xiao Zhang, 年龄: 22"
[12/06 14:47:52] [DEBUG] ProxyFactory: result:"姓名: Xiao Zhang, 年龄: 22"
如果把被代理类放到spring里面,则只能拦截到方法doWork1,其他方法拦截不到,为什么会有这种差异?
spring内部实现的问题
可以看看我之前回复的
http://www.iteye.com/topic/1125911#2368327
回答神速啊,拜读啦。。。
里面有个问题,他那个setSelf(ServiceA self)是怎么注入的
public void setSelf(ServiceA self) { this.self = self; }
我在我自己的Service直接用@Autowired报错,代码片段如下
public class UserService extends BaseService{ private UserService self; @Autowired public void setSelf(UserService self) { this.self = self; }
没找到匹配类型!错误信息:
org.springframework.beans.factory.BeanCreationException: Error creating bean with name 'studentController': Injection of autowired dependencies failed; nested exception is org.springframework.beans.factory.BeanCreationException: Could not autowire field: private com.oy.service.UserService com.oy.controller.StudentController.userService; nested exception is org.springframework.beans.factory.BeanCreationException: Error creating bean with name 'userService': Injection of autowired dependencies failed; nested exception is org.springframework.beans.factory.BeanCreationException: Could not autowire method: public void com.oy.service.UserService.setSelf(com.oy.service.UserService); nested exception is org.springframework.beans.factory.NoSuchBeanDefinitionException: No matching bean of type [com.oy.service.UserService] found for dependency: expected at least 1 bean which qualifies as autowire candidate for this dependency. Dependency annotations: {}
at org.springframework.beans.factory.annotation.AutowiredAnnotationBeanPostProcessor.postProcessPropertyValues(AutowiredAnnotationBeanPostProcessor.java:285)
at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.populateBean(AbstractAutowireCapableBeanFactory.java:1074)
at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.doCreateBean(AbstractAutowireCapableBeanFactory.java:517)
at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.createBean(AbstractAutowireCapableBeanFactory.java:456)
7 楼
jinnianshilongnian
2012-12-06
yangpeihai 写道
哥们,请教个问题,为什么spring使用cglib动态代理没法拦截被代理类的所有非private方法,而我自己写的由cglib生成的代理类却可以拦截到被代理类的所有非private方法呢?,先道声谢谢,下面贴代码:
1. 注解类,用来注解哪些方法需要写日志
2. 工厂类,由cglib生成被代理对象
3.被代理的类
4.测试类
5.结果输出:
[12/06 14:47:52] [DEBUG] ProxyFactory: Method: public java.lang.String test.log.Student.doWork1(java.lang.String,int)
[12/06 14:47:52] [DEBUG] ProxyFactory: params: ["Xiao Zhang",22]
[12/06 14:47:52] [DEBUG] ProxyFactory: Method: java.lang.String test.log.Student.doWork2(java.lang.String,int)
[12/06 14:47:52] [DEBUG] ProxyFactory: params: ["Xiao Zhang",22]
[12/06 14:47:52] [DEBUG] ProxyFactory: Method: protected java.lang.String test.log.Student.doWork3(java.lang.String,int)
[12/06 14:47:52] [DEBUG] ProxyFactory: params: ["Xiao Zhang",22]
[12/06 14:47:52] [DEBUG] ProxyFactory: result:"姓名: Xiao Zhang, 年龄: 22"
[12/06 14:47:52] [DEBUG] ProxyFactory: result:"姓名: Xiao Zhang, 年龄: 22"
[12/06 14:47:52] [DEBUG] ProxyFactory: result:"姓名: Xiao Zhang, 年龄: 22"
如果把被代理类放到spring里面,则只能拦截到方法doWork1,其他方法拦截不到,为什么会有这种差异?
1. 注解类,用来注解哪些方法需要写日志
@Target(ElementType.METHOD) @Retention(RetentionPolicy.RUNTIME) @Documented public @interface MyLog { }
2. 工厂类,由cglib生成被代理对象
public class ProxyFactory { private final static Callback DEFAULT_CALLBACK = new DefaultCallback(); private final static Log log = LogFactory.getLog(ProxyFactory.class); public static <T> T newInstance(Class<T> clazz) { return newInstance(clazz, DEFAULT_CALLBACK); } @SuppressWarnings("unchecked") public static <T> T newInstance(Class<T> clazz, Callback callback) { Enhancer enhancer = new Enhancer(); enhancer.setSuperclass(clazz); enhancer.setCallback(callback); return (T) enhancer.create(); } private static class DefaultCallback implements MethodInterceptor { @Override public Object intercept(Object obj, Method method, Object[] args, MethodProxy proxy) throws Throwable { Object result = null; //只有标志了MyLog的方法才写日志 boolean flag = method.isAnnotationPresent(MyLog.class); if(flag){ log.debug("Method: " + method.toGenericString()); log.debug("params: " + JSON.toJSONString(args)); } // 调用方法 result = proxy.invokeSuper(obj, args); if(flag){ log.debug("result:" + JSON.toJSONString(result)); } return result; } } }
3.被代理的类
public class Student { public Student() { } public static Student newProxyInstance() { return ProxyFactory.newInstance(Student.class); } @MyLog public String doWork1(String name, int age) { return doWork2(name,age); } @MyLog String doWork2(String name, int age) { return doWork3(name,age); } @MyLog protected String doWork3(String name, int age) { return doWork4(name,age); } @MyLog private String doWork4(String name, int age) { return "姓名: " + name + ", 年龄: " + age; } }
4.测试类
public class Test { public static void main(String[] args) { Student stu = Student.newProxyInstance(); stu.doWork1("Xiao Zhang", 22); } }
5.结果输出:
[12/06 14:47:52] [DEBUG] ProxyFactory: Method: public java.lang.String test.log.Student.doWork1(java.lang.String,int)
[12/06 14:47:52] [DEBUG] ProxyFactory: params: ["Xiao Zhang",22]
[12/06 14:47:52] [DEBUG] ProxyFactory: Method: java.lang.String test.log.Student.doWork2(java.lang.String,int)
[12/06 14:47:52] [DEBUG] ProxyFactory: params: ["Xiao Zhang",22]
[12/06 14:47:52] [DEBUG] ProxyFactory: Method: protected java.lang.String test.log.Student.doWork3(java.lang.String,int)
[12/06 14:47:52] [DEBUG] ProxyFactory: params: ["Xiao Zhang",22]
[12/06 14:47:52] [DEBUG] ProxyFactory: result:"姓名: Xiao Zhang, 年龄: 22"
[12/06 14:47:52] [DEBUG] ProxyFactory: result:"姓名: Xiao Zhang, 年龄: 22"
[12/06 14:47:52] [DEBUG] ProxyFactory: result:"姓名: Xiao Zhang, 年龄: 22"
如果把被代理类放到spring里面,则只能拦截到方法doWork1,其他方法拦截不到,为什么会有这种差异?
spring内部实现的问题
可以看看我之前回复的
http://www.iteye.com/topic/1125911#2368327
6 楼
yangpeihai
2012-12-06
哥们,请教个问题,为什么spring使用cglib动态代理没法拦截被代理类的所有非private方法,而我自己写的由cglib生成的代理类却可以拦截到被代理类的所有非private方法呢?,先道声谢谢,下面贴代码:
1. 注解类,用来注解哪些方法需要写日志
2. 工厂类,由cglib生成被代理对象
3.被代理的类
4.测试类
5.结果输出:
[12/06 14:47:52] [DEBUG] ProxyFactory: Method: public java.lang.String test.log.Student.doWork1(java.lang.String,int)
[12/06 14:47:52] [DEBUG] ProxyFactory: params: ["Xiao Zhang",22]
[12/06 14:47:52] [DEBUG] ProxyFactory: Method: java.lang.String test.log.Student.doWork2(java.lang.String,int)
[12/06 14:47:52] [DEBUG] ProxyFactory: params: ["Xiao Zhang",22]
[12/06 14:47:52] [DEBUG] ProxyFactory: Method: protected java.lang.String test.log.Student.doWork3(java.lang.String,int)
[12/06 14:47:52] [DEBUG] ProxyFactory: params: ["Xiao Zhang",22]
[12/06 14:47:52] [DEBUG] ProxyFactory: result:"姓名: Xiao Zhang, 年龄: 22"
[12/06 14:47:52] [DEBUG] ProxyFactory: result:"姓名: Xiao Zhang, 年龄: 22"
[12/06 14:47:52] [DEBUG] ProxyFactory: result:"姓名: Xiao Zhang, 年龄: 22"
如果把被代理类放到spring里面,则只能拦截到方法doWork1,其他方法拦截不到,为什么会有这种差异?
1. 注解类,用来注解哪些方法需要写日志
@Target(ElementType.METHOD) @Retention(RetentionPolicy.RUNTIME) @Documented public @interface MyLog { }
2. 工厂类,由cglib生成被代理对象
public class ProxyFactory { private final static Callback DEFAULT_CALLBACK = new DefaultCallback(); private final static Log log = LogFactory.getLog(ProxyFactory.class); public static <T> T newInstance(Class<T> clazz) { return newInstance(clazz, DEFAULT_CALLBACK); } @SuppressWarnings("unchecked") public static <T> T newInstance(Class<T> clazz, Callback callback) { Enhancer enhancer = new Enhancer(); enhancer.setSuperclass(clazz); enhancer.setCallback(callback); return (T) enhancer.create(); } private static class DefaultCallback implements MethodInterceptor { @Override public Object intercept(Object obj, Method method, Object[] args, MethodProxy proxy) throws Throwable { Object result = null; //只有标志了MyLog的方法才写日志 boolean flag = method.isAnnotationPresent(MyLog.class); if(flag){ log.debug("Method: " + method.toGenericString()); log.debug("params: " + JSON.toJSONString(args)); } // 调用方法 result = proxy.invokeSuper(obj, args); if(flag){ log.debug("result:" + JSON.toJSONString(result)); } return result; } } }
3.被代理的类
public class Student { public Student() { } public static Student newProxyInstance() { return ProxyFactory.newInstance(Student.class); } @MyLog public String doWork1(String name, int age) { return doWork2(name,age); } @MyLog String doWork2(String name, int age) { return doWork3(name,age); } @MyLog protected String doWork3(String name, int age) { return doWork4(name,age); } @MyLog private String doWork4(String name, int age) { return "姓名: " + name + ", 年龄: " + age; } }
4.测试类
public class Test { public static void main(String[] args) { Student stu = Student.newProxyInstance(); stu.doWork1("Xiao Zhang", 22); } }
5.结果输出:
[12/06 14:47:52] [DEBUG] ProxyFactory: Method: public java.lang.String test.log.Student.doWork1(java.lang.String,int)
[12/06 14:47:52] [DEBUG] ProxyFactory: params: ["Xiao Zhang",22]
[12/06 14:47:52] [DEBUG] ProxyFactory: Method: java.lang.String test.log.Student.doWork2(java.lang.String,int)
[12/06 14:47:52] [DEBUG] ProxyFactory: params: ["Xiao Zhang",22]
[12/06 14:47:52] [DEBUG] ProxyFactory: Method: protected java.lang.String test.log.Student.doWork3(java.lang.String,int)
[12/06 14:47:52] [DEBUG] ProxyFactory: params: ["Xiao Zhang",22]
[12/06 14:47:52] [DEBUG] ProxyFactory: result:"姓名: Xiao Zhang, 年龄: 22"
[12/06 14:47:52] [DEBUG] ProxyFactory: result:"姓名: Xiao Zhang, 年龄: 22"
[12/06 14:47:52] [DEBUG] ProxyFactory: result:"姓名: Xiao Zhang, 年龄: 22"
如果把被代理类放到spring里面,则只能拦截到方法doWork1,其他方法拦截不到,为什么会有这种差异?
5 楼
jinnianshilongnian
2012-12-05
yangpeihai 写道
哥们,请教个aop问题,如果使用cglib动态代理目标对象,是否可以拦截到目标对象的所有非private方法?请看下面:
下面是我的service代码片段
下面是我的application*.xml配置:
调试时,被代理的类又出现CGLIB字样,说明是CGLIB动态代理生成的类
现在问题是:接口方法findAll()访问时可以被拦截到,但是两个非接口测试方法调用时没有被拦截到,是不是我哪里配置少啦,指点下,多谢!
下面是我的service代码片段
[color=red]//公开的接口方法[/color] @AutoWriteLog public List findAll() { return test1("杨培海"); } [color=red]//自己测试用的方法test1[/color] @AutoWriteLog public List test1(String arg){ return test2(arg); } [color=red]//自己测试用的方法test2[/color] @AutoWriteLog List test2(String arg){ return userDao.findAll(); }
下面是我的application*.xml配置:
<aop:aspectj-autoproxy proxy-target-class="true"/> <!-- 配置哪些类的方法需要进行事务管理 --> <aop:config proxy-target-class="true"> <aop:pointcut id="allManagerMethod" expression="execution(* com.oy.service.*.*(..))" /> <aop:advisor advice-ref="txAdvice" pointcut-ref="allManagerMethod" /> <!-- 配置aspect切面类 --> <aop:aspect ref="aspect"> <!-- 配置advice,即Aspect类中的logging()方法,这里采用在业务方法执行前进行拦截 --> <!-- <aop:before method="logging" pointcut-ref="allManagerMethod" /> <aop:after method="loggout" pointcut-ref="allManagerMethod" /> --> <aop:around pointcut-ref="allManagerMethod" method="myPointCutTest"/> </aop:aspect> </aop:config>
调试时,被代理的类又出现CGLIB字样,说明是CGLIB动态代理生成的类
org.springframework.aop.framework.[color=red]Cglib[/color]2AopProxy$DynamicAdvisedInterceptor@ec596
现在问题是:接口方法findAll()访问时可以被拦截到,但是两个非接口测试方法调用时没有被拦截到,是不是我哪里配置少啦,指点下,多谢!
@AutoWriteLog
public List test1(String arg){
return test2(arg);
}
这样调用不行
原因见
http://jinnianshilongnian.iteye.com/blog/1487235
4 楼
yangpeihai
2012-12-05
哥们,请教个aop问题,如果使用cglib动态代理目标对象,是否可以拦截到目标对象的所有非private方法?请看下面:
下面是我的service代码片段
下面是我的application*.xml配置:
调试时,被代理的类又出现CGLIB字样,说明是CGLIB动态代理生成的类
现在问题是:接口方法findAll()访问时可以被拦截到,但是两个非接口测试方法调用时没有被拦截到,是不是我哪里配置少啦,指点下,多谢!
下面是我的service代码片段
[color=red]//公开的接口方法[/color] @AutoWriteLog public List findAll() { return test1("杨培海"); } [color=red]//自己测试用的方法test1[/color] @AutoWriteLog public List test1(String arg){ return test2(arg); } [color=red]//自己测试用的方法test2[/color] @AutoWriteLog List test2(String arg){ return userDao.findAll(); }
下面是我的application*.xml配置:
<aop:aspectj-autoproxy proxy-target-class="true"/> <!-- 配置哪些类的方法需要进行事务管理 --> <aop:config proxy-target-class="true"> <aop:pointcut id="allManagerMethod" expression="execution(* com.oy.service.*.*(..))" /> <aop:advisor advice-ref="txAdvice" pointcut-ref="allManagerMethod" /> <!-- 配置aspect切面类 --> <aop:aspect ref="aspect"> <!-- 配置advice,即Aspect类中的logging()方法,这里采用在业务方法执行前进行拦截 --> <!-- <aop:before method="logging" pointcut-ref="allManagerMethod" /> <aop:after method="loggout" pointcut-ref="allManagerMethod" /> --> <aop:around pointcut-ref="allManagerMethod" method="myPointCutTest"/> </aop:aspect> </aop:config>
调试时,被代理的类又出现CGLIB字样,说明是CGLIB动态代理生成的类
org.springframework.aop.framework.[color=red]Cglib[/color]2AopProxy$DynamicAdvisedInterceptor@ec596
现在问题是:接口方法findAll()访问时可以被拦截到,但是两个非接口测试方法调用时没有被拦截到,是不是我哪里配置少啦,指点下,多谢!
3 楼
gaiqiliang
2012-09-27
2 楼
jinnianshilongnian
2012-09-26
fatmonkey64 写道
跟进开涛 哥
1 楼
fatmonkey64
2012-09-26
跟进开涛 哥
发表评论
-
一段Spring代码引起的调用绑定总结
2014-03-04 07:41 15246代码 @Component public class B ... -
一段Spring代码引起的调用绑定总结
2014-03-02 10:53 0代码 @Component public class ... -
Spring Cache抽象详解
2014-01-08 07:54 150668缓存简介 缓存,我的理解是:让数据更接近于使 ... -
Spring3.1新属性管理API:PropertySource、Environment、Profile
2014-01-07 08:05 72781Spring3.1提供了新的属性管理API,而且功能非常强 ... -
Spring3.1新属性管理API:PropertySource、Environment、Profile
2014-01-07 08:04 0Spring3.1提供了新的属性管理API,而且功能非常强 ... -
Spring动态部署Bean/Controller/Groovy Controller
2014-01-06 08:00 24303最近有好几个咨询如何动态部署Bean/动态部署Spring ... -
Spring4新特性——注解、脚本、任务、MVC等其他特性改进
2013-12-25 07:58 68397Spring4新特性——泛型限定式依赖注入 Spring ... -
Spring4新特性——JSR310日期时间API的支持
2013-12-24 07:48 39114Spring4新特性——泛型限定式依赖注入 Spring ... -
Spring3.1新属性管理API:PropertySource、Environment、Profile
2013-12-23 21:44 0Spring3.1提供了新的属性管理API,而且功能非常强 ... -
Spring4新特性——更好的Java泛型操作API
2013-12-23 07:43 41683Spring4新特性——泛型限定式依赖注入 Spring ... -
Spring4新特性——Groovy Bean定义DSL
2013-12-19 07:33 37500Spring4新特性——泛型限定式依赖注入 Spring ... -
Spring4新特性——Groovy Bean定义DSL
2013-12-18 20:53 0Spring4支持使用Groovy DSL来进行Bean定 ... -
Spring4新特性——集成Bean Validation 1.1(JSR-349)到SpringMVC
2013-12-16 08:10 157592Spring4新特性——泛型限定式依赖注入 Spring ... -
Spring4新特性——集成Bean Validation 1.1(JSR-349)到SpringMVC
2013-12-15 10:51 0在之前的《跟我学SpringMVC》中的《第七章 注解式控 ... -
Spring4新特性——Web开发的增强
2013-12-14 08:12 269973Spring4新特性——泛型限定式依赖注入 Spring ... -
Spring4新特性——核心容器的其他改进
2013-12-14 07:23 47460Spring4新特性——泛型限定式依赖注入 Spring ... -
Spring4新特性——核心容器的其他改进
2013-12-13 22:54 311接上一篇《Spring4新特性——泛型限定式依赖注入》,接 ... -
Spring4新特性——泛型限定式依赖注入
2013-12-13 20:46 119207Spring4新特性——泛型限定式依赖注入 Spring ... -
Spring事务超时时间可能存在的错误认识
2013-12-06 09:36 474401、先看代码 1.1、spring-config.xml ... -
采用共享jar包部署struts2+spring集成项目会遇到的问题
2013-11-29 06:45 6264比如tomcat下边有个lib,放着我们需要的struts2 ...
相关推荐
1.13 我对SpringDAO层支持的总结 1.14 我对SpringDAO层支持的总结 1.15 我对SpringDAO层支持的总结 1.16 我对Spring 容器管理事务支持的总结 1.17 我对Spring 容器管理事务支持的总结 1.18 不重复配置——利用Spring...
Spring初探 准备工作 构建Spring基础代码 Spring 基础语义 Dependency Injection 依赖注入的几种实现类型 Type1 接口注入 Type2 设值注入 Type3 构造子注入 几种依赖注入模式的对比总结 Spring Bean封装...
13.8. Spring对分段文件上传(multipart file upload)的支持 13.8.1. 介绍 13.8.2. 使用MultipartResolver 13.8.3. 在表单中处理分段文件上传 13.9. 使用Spring的表单标签库 13.9.1. 配置标签库 13.9.2. form...
13.8. Spring对分段文件上传(multipart file upload)的支持 13.8.1. 介绍 13.8.2. 使用MultipartResolver 13.8.3. 在表单中处理分段文件上传 13.9. 使用Spring的表单标签库 13.9.1. 配置 13.9.2. form标签 ...
13.8. Spring对分段文件上传(multipart file upload)的支持 13.8.1. 介绍 13.8.2. 使用MultipartResolver 13.8.3. 在表单中处理分段文件上传 13.9. 使用Spring的表单标签库 13.9.1. 配置 13.9.2. form标签 ...
13.8. Spring对分段文件上传(multipart file upload)的支持 13.8.1. 介绍 13.8.2. 使用MultipartResolver 13.8.3. 在表单中处理分段文件上传 13.9. 使用Spring的表单标签库 13.9.1. 配置标签库 13.9.2. form...
13.5 Spring对JDK 5.0 Executor的支持 13.5.1 了解JDK 5.0的Executor 13.5.2 Spring对Executor所提供的抽象 13.6 实际应用中的任务调度 13.6.1 如何产生任务 13.6.2 任务调度对应用程序集群的影响 13.6.3 任务调度云...
13.8. Spring对分段文件上传(multipart file upload)的支持 13.8.1. 介绍 13.8.2. 使用MultipartResolver 13.8.3. 在表单中处理分段文件上传 13.9. 使用Spring的表单标签库 13.9.1. 配置标签库 13.9.2. form标签 ...
SSH整合示例(详情见我博客专栏)之前的博客我们总结了spring基础、spring分别整合struts2、hibernate、mybatis等,今天我们来同时整合下 struts、spring、hibernate,也就是所谓的 ssh 。 整合流程: 1 首先整合...
13.5 Spring对JDK 5.0 Executor的支持 13.5.1 了解JDK 5.0的Executor 13.5.2 Spring对Executor所提供的抽象 13.6 实际应用中的任务调度 13.6.1 如何产生任务 13.6.2 任务调度对应用程序集群的影响 13.6.3 任务调度云...
Spring+SpringMVC+mybatist三大框架整合项目,java代码分为 dao,service,controller三层,支持注 解,事务。数据库默认MySQL,配置文件为src下的config资源包中的 db.properties,以KEY VALUE形式保存数据库连接属性...
在对由三部分组成的 Spring 系列 的第 1 部分进行总结时,我使用了一个示例,演示了如何通过 Spring IOC 容器注入应用程序的依赖关系(而不是将它们构建进来)。 我用开启在线信用帐户的用例作为起点。对于该实现,...
后来项目结束了,我也没写总结文档。已经过去好久了。但最近突然又对这个ORM 工具感兴趣。因为接下来自己的项目中很有可能采用这个ORM工具。所以在此重新温习了一下 mybatis, 因此就有了这个系列的 mybatis 教程. ...
太原理工大学JavaEE实验报告 Mybatis实验 Spring实验 ...mybatis是一款半自动的ORM持久层框架,具有较高的SQL灵活性,支持高级映射(一对一,一对多),动态SQL,延迟加载和缓存等特性,但它的数据库无关性较低
5.2.2 开发并配置Hibernate DAO层 38 5.3 控制层Struts实现 38 5.3.1 开发Struts核心流程代码 38 5.3.2 开发JSP页面原型 40 5.3.3 增加表单校验功能 40 5.3.4 调用DAO组件操作数据库 41 5.4 业务层Spring实现 41 ...
需要指定的是Spring 1.2.5提供了两套Hibernate的支持包,其中Hibernate 2相关的封装类位于org.springframework.orm.hibernate2.*包中,而Hibernate 3.0的封装类位于org.springframework.orm.hibernate3.*包中,...
搜索服务-dao层.avi │ 05.搜索服务-Service.avi │ 06.搜索服务-发布.avi │ 07.搜索实现-分析.avi │ 08.搜索实现-Service.avi │ 09.搜索实现-Controller.avi │ 10.搜索功能测试.avi │ 11.zookeeper的介绍.avi ...