Spring生成代理对象的过程
1. 创建容器对象的时候, 根据“切入点表达式”拦截的类,生成代理对象;
2. 如果目标对象有实现接口,使用jdk代理!
3. 如果目标对象没有实现接口,使用cglib代理!
4. 从容器获取代理后的对象
5. 执行代理对象的方法,在运行时期,动态织入“切面”类中的“通知”!
1.注解行式
1.1引入aop名称空间,开启aop注解
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18
| <beans xmlns="http://www.springframework.org/schema/beans" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" 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.xsd http://www.springframework.org/schema/context http://www.springframework.org/schema/context/spring-context.xsd http://www.springframework.org/schema/aop http://www.springframework.org/schema/aop/spring-aop.xsd"> <context:component-scan base-package="cn.itcast.e_aop_anno"></context:component-scan> <aop:aspectj-autoproxy></aop:aspectj-autoproxy> </beans>
|
1.2 使用Aop相关注解
@Aspect
指定一个类为切面类(切面类也需要实例化)(切面类中的方法,也叫做通知)
@Before
前置通知 【在执行目标对象方法之前执行】
@After
后置通知 【在执行目标对象方法之后执行】
@AfterReturning
返回后通知 【在执行目标对象方法结束后执行, 出现异常不执行】
@AfterThrowing
异常通知 【在执行目标对象方法出现异常时候执行】
@Around
环绕通知 【环绕目标方法执行】
@Pointcut
定义一个切入点表达式变量 (后面使用这个切入点表达式的时候,直接引用方法名即可)
代码示例
1 2 3 4 5 6 7 8 9 10 11 12 13 14
| public interface IUserDao {
void save();
}
@Repository public class UserDao implements IUserDao { public void save() { System.out.println("保存..."); } }
|
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45
| @Component("aop") @Aspect public class TransactionAop { @Pointcut("execution(* cn.itcast.e_aop_anno.UserDao.*(..))") public void pointcut_(){ }
@Before("pointcut_()") public void beginTransaction() { System.out.println("[前置通知] 开启事务.."); } @After("pointcut_()") public void commit() { System.out.println("[后置通知] 提交事务.."); } @AfterReturning("pointcut_()") public void afterReturing(){ System.out.println("[返回后通知]"); } @AfterThrowing("pointcut_()") public void afterThrowing(){ System.out.println("[异常通知]"); } @Around("pointcut_()") public void arroud(ProceedingJoinPoint pjp) throws Throwable{ System.out.println("[环绕前:]"); pjp.proceed(); System.out.println("[环绕后:]"); }
}
|
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44
| public class App {
private ApplicationContext ac = new ClassPathXmlApplicationContext("applicationContext.xml",getClass()); @Test public void testApp() throws Exception {
UserDao userDao = (UserDao) ac.getBean("userDao"); System.out.println(userDao.getClass()); userDao.save(); } @Test public void testApp_cglib() throws Exception { UserDao userDao = (UserDao) ac.getBean("userDao"); System.out.println(userDao.getClass()); userDao.save(); } @Test public void testApp_save_order() throws Exception { OrderDao orderDao = (OrderDao) ac.getBean("orderDao"); System.out.println(orderDao.getClass()); orderDao.save(); } }
|
2.XML配置
代码示例
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47
| <?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: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.xsd http://www.springframework.org/schema/context http://www.springframework.org/schema/context/spring-context.xsd http://www.springframework.org/schema/aop http://www.springframework.org/schema/aop/spring-aop.xsd"> <bean id="userDao" class="cn.itcast.f_aop_xml.UserDao"></bean> <bean id="aop" class="cn.itcast.f_aop_xml.TransactionAop"></bean> <aop:config> <aop:pointcut expression="execution(* cn.itcast.f_aop_xml.UserDao.*(..))" id="pt"/> <aop:aspect ref="aop"> <aop:around method="arroud" pointcut-ref="pt"/> <aop:before method="beginTransaction" pointcut-ref="pt" /> <aop:after method="commit" pointcut-ref="pt"/> <aop:after-returning method="afterReturing" pointcut-ref="pt"/> <aop:after-throwing method="afterThrowing" pointcut-ref="pt"/> </aop:aspect> </aop:config> </beans>
|