dao层
package com.yaorange.dao;
public interface StudentDao {
public void saveStudent();
public void deleteStudent();
}
dao层的实现
package com.yaorange.dao.impl;
import com.yaorange.dao.StudentDao;
public class StudentDaoImpl implements StudentDao{
@Override
public void saveStudent() {
System.out.println("saveStudent");
}
@Override
public void deleteStudent() {
System.out.println("deleteStudent");
}
}
工具层
第一个是工厂制造studentDao
package com.yaorange.utils;
import java.lang.reflect.InvocationHandler;
import java.lang.reflect.Method;
import java.lang.reflect.Proxy;
import com.yaorange.dao.StudentDao;
import com.yaorange.dao.impl.StudentDaoImpl;
public class MyFactory {
public static StudentDao createStudentProxy(){
final StudentDao studentDaoImpl = new StudentDaoImpl();
final StudentAspect studentAspect = new StudentAspect();
StudentDao studentDao = (StudentDao) Proxy.newProxyInstance(MyFactory.class.getClassLoader(),
studentDaoImpl.getClass().getInterfaces(),
new InvocationHandler() {
public Object invoke(Object proxy, Method method, Object[] args) throws Throwable {
studentAspect.before();
Object object = method.invoke(studentDaoImpl, args);
studentAspect.after();
return object;
}
});
return studentDao;
}
}
StudentAspect是学生的一个aspect
package com.yaorange.utils;
import org.aopalliance.intercept.MethodInterceptor;
import org.aopalliance.intercept.MethodInvocation;
public class StudentAspect implements MethodInterceptor{
//开始事务
public void before(){
System.out.println("开始事务");
}
//提交事务
public void after(){
System.out.println("提交事务");
}
@Override
public Object invoke(MethodInvocation mi) throws Throwable {
before();
Object object = mi.proceed();
after();
return object;
}
}
手动的是不写beans.xml的
<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans"
xmlns:aop="http://www.springframework.org/schema/aop"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
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 id="studentDaoImpl" class="com.yaorange.dao.impl.StudentDaoImpl"/>
<!--创建切面类 -->
<bean id="studentAspect" class="com.yaorange.utils.StudentAspect"/>
<!-- 3 创建代理类
* 使用工厂bean FactoryBean ,底层调用 getObject() 返回特殊bean
* ProxyFactoryBean 用于创建代理工厂bean,生成特殊代理对象
interfaces : 确定接口们
通过<array>可以设置多个值
只有一个值时,value=""
target : 确定目标类
interceptorNames : 通知 切面类的名称,类型String[],如果设置一个值 value=""
optimize :强制使用cglib
<property name="optimize" value="true"></property>
底层机制
如果目标类有接口,采用jdk动态代理
如果没有接口,采用cglib 字节码增强
如果声明 optimize = true ,无论是否有接口,都采用cglib
-->
<!--代理类 -->
<bean id="proxyStudentDao" class="org.springframework.aop.framework.ProxyFactoryBean">
<property name="optimize" value="true"/>
<property name="interfaces" value="com.yaorange.dao.StudentDao"/>
<property name="target" ref="studentDaoImpl"/>
<property name="interceptorNames" value="studentAspect"></property>
</bean>
<!-- **********************全自动 ************************-->
<!-- 目标类 -->
<bean id="studentDaoImpl2" class="com.yaorange.dao.impl.StudentDaoImpl"/>
<!-- *******************切面类************************* -->
<bean id="studentAspect2" class="com.yaorange.utils.StudentAspect"/>
<aop:config>
<!-- *代表匹配 匹配这个包 匹配包里面的类 匹配类中的方法 .代表方法中的参数 -->
<aop:pointcut expression="excution(* com.yaorange.utils.*.*(..))" id="mypointcut"/>
<aop:advisor advice-ref="studentAspect2" pointcut-ref="mypointcut"/>
</aop:config>
</beans>
最后是我们的测试类
package com.yaorange.test;
import org.junit.Test;
import org.springframework.context.support.ClassPathXmlApplicationContext;
import com.yaorange.dao.StudentDao;
import com.yaorange.utils.MyFactory;
public class AOPTest {
//手动
@Test
public void test1(){
StudentDao studentDao = MyFactory.createStudentProxy();
studentDao.saveStudent();
}
//半自动
@Test
public void test2(){
ClassPathXmlApplicationContext cpx = new ClassPathXmlApplicationContext("beans.xml");
StudentDao studentDao = (StudentDao) cpx.getBean("proxyStudentDao");
studentDao.saveStudent();
studentDao.deleteStudent();
}
//全自动
@Test
public void test3(){
StudentDao studentDao = MyFactory.createStudentProxy();
studentDao.saveStudent();
}
}