Spring--AOP--面向切面编程
AOP: 面向切面编程. 通过动态代理实现.
AOP就3条线, 2条线给剪断.
实现:动态代理
如果实现interface的话, 用Proxy, InvocationHandler.
不实现interface的话, 用cglib操作二进制码实现.
AOP用在哪里:
性能, 日志, 权限检查, transaction.
项目里如何使用: 声明式事务管理.
JDK提供了两个提供动态代理的类: Proxy, InvocationHandler.
UserServiceTest.java:
package com.bjsxt.service; import java.lang.reflect.Proxy; import org.junit.Test; import com.bjsxt.aop.LogInterceptor; import com.bjsxt.dao.UserDAO; import com.bjsxt.dao.impl.UserDAOImpl; import com.bjsxt.model.User; import com.bjsxt.spring.BeanFactory; import com.bjsxt.spring.ClassPathXmlApplicationContext;
public class UserServiceTest { @Test public void testProxy() { UserDAO userDAO = new UserDAOImpl(); LogInterceptor li = new LogInterceptor(); li.setTarget(userDAO); UserDAO userDAOProxy = (UserDAO)Proxy.newProxyInstance(userDAO.getClass().getClassLoader(), userDAO.getClass().getInterfaces(), li); System.out.println(userDAOProxy.getClass()); userDAOProxy.delete(); userDAOProxy.save(new User()); } }
代理 LogInterceptor.java:
package com.bjsxt.aop; import java.lang.reflect.InvocationHandler; import java.lang.reflect.Method; public class LogInterceptor implements InvocationHandler { private Object target; public Object getTarget() { return target; } public void setTarget(Object target) { this.target = target; } public void beforeMethod(Method m) { System.out.println(m.getName() + " start"); } public Object invoke(Object proxy, Method m, Object[] args) throws Throwable { beforeMethod(m); m.invoke(target, args); return null; } }
UserDAOImpl.java:
package com.bjsxt.dao.impl; import com.bjsxt.dao.UserDAO; import com.bjsxt.model.User; public class UserDAOImpl implements UserDAO { public void save(User user) { System.out.println("user saved!"); } public void delete() { System.out.println("user deteleted"); } }
UserDAO.java:
package com.bjsxt.dao; import com.bjsxt.model.User; public interface UserDAO { public void save(User user); public void delete(); }