Javaweb框架学习文章索引点这里
AOP介绍:
AOP在Spring中的实现:
- 在Spring中aop底层使用代理机制进行实现
- 如果有接口是和实现类则使用jdk中的动态代理方式即Proxy
- 如果没有接口,只有实现类则采用cglib字节码增强方式
Spring中AOP术语:
以下例子主要是事务实现
手动使用动态代理:
切入点类:
public interface BookService {
public void addBook();
public void deleteBook();
public void selectBook();
}
public class BookServiceImpl implements BookService{
@Override
public void addBook() {
System.out.println("add books");
}
@Override
public void deleteBook() {
System.out.println("delete books");
}
@Override
public void selectBook() {
System.out.println("select books");
}
}
通知类:
public class MyAspect {
public void before(String methodName) {
System.out.println("before:"+methodName);
}
public void after(String methodName) {
System.out.println("after:"+methodName);
}
}
动态代理及测试类:
package com.g_a_aop_jdk;
import java.lang.reflect.InvocationHandler;
import java.lang.reflect.Method;
import java.lang.reflect.Proxy;
import org.junit.Test;
public class MyFactory {
public BookService createBookService() {
BookService bookService = new BookServiceImpl();
MyAspect aspect = new MyAspect();
BookService proxyService = (BookService)Proxy.newProxyInstance(
MyFactory.class.getClassLoader(),
bookService.getClass().getInterfaces(),
new InvocationHandler() {
//动态代理其实就是基于接口生成的代理类,每个代理类中的方法都调用invoke方法来增强原来的方法
@Override
public Object invoke(Object proxy, Method method, Object[] args) throws Throwable {
//执行事务逻辑
aspect.before(method.getName());
Object object = method.invoke(bookService, args);//调用原来的方法
aspect.after(method.getName());
return object;
}
});
return proxyService;
}
@Test
public void test1() {
BookService bookService = createBookService();
bookService.addBook();
bookService.deleteBook();
bookService.selectBook();
}
}
结果:
before:addBook
add books
after:addBook
before:deleteBook
delete books
after:deleteBook
before:selectBook
select books
after:selectBook
手动使用cglib:
切入点类:
public class BookServiceImpl{
public void addBook() {
System.out.println("add books");
}
public void deleteBook() {
System.out.println("delete books");
}
public void selectBook() {
System.out.println("select books");
}
}
通知类:
public class MyAspect {
public void before(String methodName) {
System.out.println("before:"+methodName);
}
public void after(String methodName) {
System.out.println("after:"+methodName);
}
}
cglib和测试类
public class MyFactory {
public BookServiceImpl createBookService() {
BookServiceImpl bookService = new BookServiceImpl();
MyAspect aspect = new MyAspect();
/*cglib是对于目标类生成它的子类对象作为代理类*/
Enhancer enhancer = new Enhancer();
enhancer.setSuperclass(bookService.getClass());//确定父类,这里即是目标类
enhancer.setCallback(new MethodInterceptor() {//设置回调函数
@Override
public Object intercept(Object proxy, Method method, Object[] args, MethodProxy methodProxy) throws Throwable {
//执行原来的方法和进行增强
aspect.before(method.getName());
//Object object = method.invoke(bookService, args);
//效果同上,proxy表示的代理对象的父类对象,即是目标对象
Object object = methodProxy.invokeSuper(proxy, args);//执行原来的方法
aspect.after(method.getName());
return object;
}
});
BookServiceImpl proxyService = (BookServiceImpl)enhancer.create();
return proxyService;
}
@Test
public void test1() {
BookServiceImpl bookService = createBookService();
bookService.addBook();
bookService.deleteBook();
bookService.selectBook();
}
}
结果同上
使用Spring内置的动态代理工厂(半自动):
切入点类:
public interface BookService {
public void addBook();
public void deleteBook();
public void selectBook();
}
package com.g_b_Factorybean;
public class BookServiceImpl implements BookService{
public void addBook() {
System.out.println("add books");
}
public void deleteBook() {
System.out.println("delete books");
}
public void selectBook() {
System.out.println("select books");
}
}
通知类:
package com.g_b_Factorybean;
import org.aopalliance.intercept.MethodInterceptor;
import org.aopalliance.intercept.MethodInvocation;
//采用“环绕通知” MethodInterceptor
public class MyAspect implements MethodInterceptor{
@Override
public Object invoke(MethodInvocation mi) throws Throwable {
System.out.println("before1");
//环绕通知要手动执行目标方法
Object object = mi.proceed();
System.out.println("after1");
return object;
}
}
配置文件:
<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"
xsi:schemaLocation="http://www.springframework.org/schema/beans
http://www.springframework.org/schema/beans/spring-beans.xsd">
<bean name="BookService" class="com.g_b_Factorybean.BookServiceImpl">bean>
<bean name="MyAspect" class="com.g_b_Factorybean.MyAspect">bean>
<bean name="ProxyService" class="org.springframework.aop.framework.ProxyFactoryBean">
<property name="interfaces" value="com.g_b_Factorybean.BookService">property>
<property name="target" ref="BookService">property>
<property name="interceptorNames" value="MyAspect">property>
bean>
beans>
测试类:
@Test
public void test1() {
String xmlPath = "com/g_b_Factorybean/beans.xml";
ApplicationContext appcont = new ClassPathXmlApplicationContext(xmlPath);
BookService bookService = (BookService) appcont.getBean("ProxyService");
bookService.addBook();
bookService.selectBook();
bookService.deleteBook();
}
结果:
before1
add books
after1
before1
select books
after1
before1
delete books
after1
使用Spring AOP编程(全自动):
切入点类:
package com.g_c_aopbyspring;
public interface BookService {
public void addBook();
public void deleteBook();
public void selectBook();
}
package com.g_c_aopbyspring;
public class BookServiceImpl implements BookService{
public void addBook() {
System.out.println("add books");
}
public void deleteBook() {
System.out.println("delete books");
}
public void selectBook() {
System.out.println("select books");
}
}
通知类:
package com.g_c_aopbyspring;
import org.aopalliance.intercept.MethodInterceptor;
import org.aopalliance.intercept.MethodInvocation;
//采用“环绕通知” MethodInterceptor
public class MyAspect implements MethodInterceptor{
@Override
public Object invoke(MethodInvocation mi) throws Throwable {
System.out.println("before2");
//手动执行目标方法
Object object = mi.proceed();
System.out.println("after2");
return object;
}
}
配置文件:
<beans xmlns="http://www.springframework.org/schema/beans"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xmlns:aop="http://www.springframework.org/schema/aop"
xsi:schemaLocation="http://www.springframework.org/schema/beans
http://www.springframework.org/schema/beans/spring-beans.xsd
http://www.springframework.org/schema/aop
http://www.springframework.org/schema/aop/spring-aop.xsd
">
<bean name="BookService" class="com.g_c_aopbyspring.BookServiceImpl">bean>
<bean name="MyAspect" class="com.g_c_aopbyspring.MyAspect">bean>
<aop:config>
<aop:pointcut expression="execution(* com.g_c_aopbyspring.*.*(..))" id="myPointCut"/>
<aop:advisor advice-ref="MyAspect" pointcut-ref="myPointCut"/>
aop:config>
beans>
测试类:
@Test
public void test1() {
String xmlPath = "com/g_c_aopbyspring/beans.xml";
ApplicationContext appcont = new ClassPathXmlApplicationContext(xmlPath);
//就是直接使用原来的id名,但是获取到的已经是装饰过的对象
BookService bookService = (BookService) appcont.getBean("BookService");
bookService.addBook();
bookService.selectBook();
bookService.deleteBook();
}
结果:
add books
after2
before2
select books
after2
before2
delete books
after2