版权声明:本文为博主原创文章,未经博主允许不得转载。 https://blog.csdn.net/sinat_35512245/article/details/52871400
首先我们可以新建一个包,目录结构如下:
User类:
package com.hqj.aop; public class User { @Override public String toString() { return "User [username=" + username + ", password=" + password + "]"; } 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; } }
User类接口:
package com.hqj.aop; public interface UserDao { public void save(User user); }
User类接口类实现:
package com.hqj.aop; public class UserDaoImpl implements UserDao { public void save(User user) { System.out.println("User is saved successfully"); } }
LogInterceptor类:
public class LogInterceptor { public void before() { System.out.println("method state"); } public void after() { System.out.println("method after"); } public void AfterReturning() { System.out.println("method AfterReturning"); } public void AfterThrowing() { System.out.println("method AfterThrowing"); } }
AOP 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:p="http://www.springframework.org/schema/p" 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-4.1.xsd http://www.springframework.org/schema/aop http://www.springframework.org/schema/aop/spring-aop-4.1.xsd "> <bean id="user" class="com.hqj.aop.User"> <property name="username" value="Tim"></property> <property name="password" value="123"></property> </bean> <!-- 配置Bean --> <bean id="UserDaoImpl" class="com.hqj.aop.UserDaoImpl"></bean> <!-- 配置切面的Bean --> <!-- 也就是要记录的数据的地方 (比如错误日志) --> <bean id="logInterceptor" class="com.hqj.aop.LogInterceptor"></bean> <!-- 配置AOP --> <aop:config proxy-target-class="true"> <!-- 配置切点表达式 --> <aop:pointcut expression="execution(* com.hqj.aop.UserDao.save(..))" id="servicePointcut" /> <!-- 配置切面以及通知(指向切面,比如错误日志) --> <aop:aspect id="logAspect" ref="logInterceptor"> <!-- method写切面中(比如错误日志)的方法名称 --> <aop:before method="before" pointcut-ref="servicePointcut" /> <aop:after method="after" pointcut-ref="servicePointcut" /> </aop:aspect> </aop:config> </beans>
测试MAIN函数:
package com.hqj.aop; import org.springframework.beans.factory.BeanFactory; import org.springframework.context.ApplicationContext; import org.springframework.context.support.ClassPathXmlApplicationContext;
public class Main { public static void main(String[] args) { // TODO Auto-generated method stub ApplicationContext ctx = new ClassPathXmlApplicationContext("aop.xml"); UserDaoImpl UDI = (UserDaoImpl) ctx.getBean("UserDaoImpl"); User user = (User) ctx.getBean("user"); UDI.save(user); } }
运行结果:
常见错误:
com.sun.proxy.$Proxy2 cannot be cast to com.hqj.aop.UserDaoImpl at com.hqj.aop.Main.main(Main.java:12)
解决办法:
<tx:annotation-driven transaction-manager="transactionManager" proxy-target-class="true"/> 注意:proxy-target-class属性值决定是基于接口的还是基于类的代理被创建。如果proxy-target-class 属性值被设置为true,那么基于类的代理将起作用(这时需要cglib库)。如果proxy-target-class属值被设置为false或者这个属性被省略,那么标准的JDK 基于接口的代理将起作用。 即使你未声明 proxy-target-class="true" ,但运行类没有继承接口,spring也会自动使用CGLIB代理。高版本spring自动根据运行类选择 JDK 或 CGLIB 代理package com.hqj.aop;