1、spring的半自动代理(从spring中获取代理对象)
(1)spring中的通知类型
spring中aop的通知类型有五种:
前置:在目标方法执行前实施加强
后置:在目标方法执行后实施加强
环绕:在目标方法执行前后实施加强,必须手动执行目标方法,如果只在目标方法前面书写方法,就叫前置通知,前置通知可以阻止目标方法的执行,因为抛出异常后进入catch块,后置通知可以获得方法的返回值。
异常:在方法抛出异常后实施加强
引介:在目标类中添加一些新的方法和属性
(2)导入jar包
核心:4+1
aop:aop联盟(规范)、spring-aop(实现)
(3)创建目标类接口和接口的实现类:
public interface StudentService { void addStudent(); void updateStudent(); void deleteStudent(); }
public class StudentServiceImpl implements StudentService{ @Override public void addStudent() { System.out.println("addStudent"); } @Override public void updateStudent() { System.out.println("updateStudent"); } @Override public void deleteStudent() { System.out.println("deleteStudent"); } }
(4)创建切面:
public class MyAspect implements MethodInterceptor { @Override public Object invoke(MethodInvocation methodInvocation) throws Throwable { System.out.println("前"); methodInvocation.proceed(); System.out.println("后"); return null; } }
(5)配置文件:
<?xml version="1.0" encoding="UTF-8"?> <beans xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns="http://www.springframework.org/schema/beans" xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans-4.2.xsd"> <!--目标类--> <bean id="studentService" class="pers.zhb.proxy.StudentServiceImpl"></bean> <!--切面类--> <bean id="myAspect" class="pers.zhb.proxy.MyAspect"></bean> <!--代理类 用于创建代理工厂bean,生成特殊代理对象 --> <bean id="proxystudentService" class="org.springframework.aop.framework.ProxyFactoryBean"> <property name="interfaces" value="pers.zhb.proxy.StudentService"> </property><!--确定接口--> <property name="target" ref="studentService"></property><!--目标类--> <property name="interceptorNames" value="myAspect"></property><!--切面类的名称--> </bean> </beans>
<property name="optimize" value="true"></property><!--强制使用cglib-->
如果目标类有接口使用jdk动态代理,没有接口的话采用cglib字节码增强。如果声明为true,则无论是否有接口都是采用cglib
(6)测试:
public class TestFactoryBean { public static void main(String[] args) { ApplicationContext applicationContext=new ClassPathXmlApplicationContext("applicationContext.xml"); StudentService studentService= (StudentService) applicationContext.getBean("proxystudentService"); studentService.addStudent(); studentService.deleteStudent(); studentService.updateStudent(); } }
前
addStudent
后
前
deleteStudent
后
前
updateStudent
后
2、全自动(从spring容器获得目标类,如果配置aop,spring将自动生成代理)
(1)导包:
要确定目标类,aspectj切入点表达式,导入jar包:
(2)创建目标类接口和接口的实现类:
public interface StudentService { void addStudent(); void updateStudent(); void deleteStudent(); }
public class StudentServiceImpl implements StudentService{ @Override public void addStudent() { System.out.println("addStudent"); } @Override public void updateStudent() { System.out.println("updateStudent"); } @Override public void deleteStudent() { System.out.println("deleteStudent"); } }
(3)切面:
public class MyAspect implements MethodInterceptor { @Override public Object invoke(MethodInvocation methodInvocation) throws Throwable { System.out.println("前"); methodInvocation.proceed(); System.out.println("后"); return null; } }
(4)配置文件:
<?xml version="1.0" encoding="UTF-8"?> <beans xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:aop="http://www.springframework.org/schema/aop" xmlns="http://www.springframework.org/schema/beans" 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="studentService" class="pers.zhb.proxy.StudentServiceImpl"></bean> <!--切面类--> <bean id="myAspect" class="pers.zhb.proxy.MyAspect"></bean> <!--aop编程--> <aop:config > <!--从目标对象获得具体方法,使用了切入点表达式--> <aop:pointcut id="myPointCut" expression="execution(* pers.zhb.proxy.*.*(..))"></aop:pointcut> <aop:advisor advice-ref="myAspect" pointcut-ref="myPointCut"></aop:advisor><!--特殊的通知,只有一个通知和切入点--> </aop:config> </beans>
(5)测试类:
public class TestFactoryBean {
public static void main(String[] args) {
ApplicationContext applicationContext=new
ClassPathXmlApplicationContext("applicationContext.xml");
//获得目标类
StudentService studentService= (StudentService) applicationContext.getBean("studentService");
studentService.addStudent();
studentService.deleteStudent();
studentService.updateStudent();
}
}
前
addStudent
后
前
deleteStudent
后
前
updateStudent
后