Spring笔记4

1.   不用Aop使用jdk的代理实现拦截,PersonServiceBean要求必须实现接口

接口
1 package cn.itcast.service;
2 
3 public interface PersonService {
4 
5     public abstract void save();
6 
7 }
被拦截的类
 1 package cn.itcast.service.impl;
 2 
 3 import cn.itcast.service.PersonService;
 4 
 5 public class PersonServiceBean implements PersonService {
 6     
 7     
 8     public String name;
 9     
10     public PersonServiceBean() {
11     }
12     
13     public PersonServiceBean(String name) {
14         this.name = name;
15     }
16 
17     public void save(){
18         System.out.println("我是sava方法");
19     }
20 
21     public String getName() {
22         return name;
23     }
24     
25 }
代理类 
2.  如果类没有实现接口使用cglib实现 ,导入.../lib/cglib下的cglib-nodep-2.1_3.jar文件
代理类
 1 package cn.itcast.aop;
 2 
 3 import java.lang.reflect.Method;
 4 
 5 import cn.itcast.service.impl.PersonServiceBean;
 6 
 7 import net.sf.cglib.proxy.Enhancer;
 8 import net.sf.cglib.proxy.MethodInterceptor;
 9 import net.sf.cglib.proxy.MethodProxy;
10 
11 public class CGlibFactory implements MethodInterceptor{
12     public Object tagetObject;
13     
14     public Object createProxyInstance(Object tagetObject){
15         this.tagetObject = tagetObject;
16         Enhancer enhancer = new Enhancer();
17         //指定父类,重写父类的所有非final方法
18         enhancer.setSuperclass(this.tagetObject.getClass());
19         //指定回调函数,类实现MethodInterceptor接口
20         enhancer.setCallback(this);
21         return enhancer.create();
22     }
23 
24     @Override
25     public Object intercept(Object proxy, Method method, Object[] args,
26             MethodProxy methodProxy) throws Throwable {
27         PersonServiceBean bean = (PersonServiceBean)this.tagetObject;
28         Object result=null;
29         if(bean.getName()!=null){
30             //将方法的调用委派给目标对象
31             result = methodProxy.invoke(tagetObject, args);
32         }
33         return null;
34     }
35 }
测试类
 1 package cn.itcast.test;
 2 
 3 import org.junit.Test;
 4 
 5 import cn.itcast.aop.CGlibFactory;
 6 import cn.itcast.aop.ProxyFactroy;
 7 import cn.itcast.service.PersonService;
 8 import cn.itcast.service.impl.PersonServiceBean;
 9 
10 public class AopTest {
11     @Test public void aopTest(){
12         ProxyFactroy factory = new ProxyFactroy();
13         //PersonService用接口类,传参的时候用非接口类,传名字的时候正常,不传名字的时候被拦截
14         PersonService service = (PersonService) factory.createProxyInstance(new PersonServiceBean("xxx"));
15         service.save();
16     }
17     @Test public void aopTest2(){
18         CGlibFactory factory = new CGlibFactory();
19         //传名字的时候正常,不传名字的时候被拦截
20         PersonServiceBean service = (PersonServiceBean) factory.createProxyInstance(new PersonServiceBean("xxx"));
21         service.save();
22     }
23 }

3.  AOP的概念:

  Aspect(切面):对横切性关注点的一个抽象,比如上面的Factory类

  joinpoint(连接点):指被拦截到的点,在Spring中指方法,比如上面的save方法

  Pointcut(切入点):是指我们要对哪些joinpoint进行拦截的定义

  Advice(通知):指拦截到joinpoint之后要做的事情,通知分为前置通知,后置通知,例外通知,最终通知,环绕通知

  Target(目标对象):代理的目标对象

  Weave(织入):将Aspect应用到target对象并导致Proxy对象创建的过程

  Introduction(引入):在不修改代码的前提下,Introduction可以为类动态的添加一些方法或Field

4.  使用Spring的aop实现切面编程:

  1)引入aop的jar包

  2)加入命名空间,第5,10行,第11行打开aop注解

 1 <?xml version="1.0" encoding="UTF-8"?>
 2 <beans xmlns="http://www.springframework.org/schema/beans"
 3        xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
 4        xmlns:context="http://www.springframework.org/schema/context"
 5        xmlns:aop="http://www.springframework.org/schema/aop" 
 6        xsi:schemaLocation="http://www.springframework.org/schema/beans
 7            http://www.springframework.org/schema/beans/spring-beans-2.5.xsd
 8            http://www.springframework.org/schema/context 
 9            http://www.springframework.org/schema/context/spring-context-2.5.xsd
10            http://www.springframework.org/schema/aop http://www.springframework.org/schema/aop/spring-aop-2.5.xsd ">
11     <aop:aspectj-autoproxy></aop:aspectj-autoproxy>
12 </beans>

  3)创建要拦截的bean以及接口

 1 package cn.itcast.service;
 2 
 3 
 4 import java.util.List;
 5 import java.util.Map;
 6 import java.util.Properties;
 7 import java.util.Set;
 8 
 9 public interface PersonService {
10 
11     public abstract void save();
12     public abstract void update();
13     public abstract String getPeresonName();
14 }
 1 package cn.itcast.service.imp;
 2 
 3 import cn.itcast.service.PersonService;
 4 
 5 public class PersonServiceBean implements PersonService {
 6     
 7     @Override
 8     public String getPeresonName() {
 9         return "xxx";
10         
11     }
12 
13     @Override
14     public void update() {
15         System.out.println("update");
16         
17     }
18 
19     @Override
20     public void save() {
21         System.out.println("save");
22         
23     }
24     
25 }

  4)创建切面,切入点,以及前置通知

 1 package cn.itcast.service;
 2 
 3 import org.aspectj.lang.annotation.Aspect;
 4 import org.aspectj.lang.annotation.Before;
 5 import org.aspectj.lang.annotation.Pointcut;
 6 
 7 @Aspect//切面
 8 public class Interceptor {
 9     //切入点,(返回值,然后是包名,类名,方法,参数)*代表任意,..代表所有
10     @Pointcut("execution(* cn.itcast.service.imp.PersonServiceBean.*(..))")
11     private void anyWethod(){}//声明一个切入点
12     
13     //前置通知,参数为切入点
14     @Before("anyWethod()")
15     public void doAcessCheak(){
16         System.out.println("前置通知");
17     }
18     
19 }

  5)将切面以及bean交给Spring管理

1 <bean id="myInterceptor" class="cn.itcast.service.Interceptor"></bean>
2 <bean id="personService" class="cn.itcast.service.imp.PersonServiceBean"></bean>

  6)测试

ApplicationContext ctr = new ClassPathXmlApplicationContext("beans.xml");
PersonService personService = (PersonService) ctr.getBean("personService");
personService.save();

控制台会输出前置通知的内容,然后输出save方法中的内容

5.  前置通知

1 @Before("anyWethod()")
2     public void doAcessCheck(){
3         System.out.println("前置通知");
4     }
@Before("anyWethod() && args(name)")//表示拦截参数为一个且是String类型的方法
    public void doAcessCheck(String name){
        System.out.println("前置通知"+name);
    }

6.  后置通知

1 @AfterReturning("anyWethod()")
2     public void doAccessCheckAfter(){
3         System.out.println("后置通知");
4     }
1 @AfterReturning(pointcut="anyWethod()" ,returning="result" )//表示拦截返回值为String类型的方法
2     public void doAccessCheckAfter(String result){
3         System.out.println("后置通知"+result);
4     }

7.  最终通知

1 @After("anyWethod()")
2     public void doAfter(){
3         System.out.println("最终通知");
4     }

8  例外通知

1 @AfterThrowing("anyWethod()")
2     public void dofterThrowing(){
3         System.out.println("例外通知");
4     }
1 @AfterThrowing(pointcut="anyWethod()",throwing="e")//表示拦截参数为Exception的异常
2     public void dofterThrowing(Exception e){
3         System.out.println("例外通知"+e);
4     }

9.  环绕通知

1 @Around("anyWethod()")
2     public Object doAround(ProceedingJoinPoint pjp) throws Throwable{
3         System.out.println("进入方法");
4         Object result =  pjp.proceed();
5         System.out.println("退出方法");
6         return result;
7     }

10.  用xml方式实现,不使用注解

 1 <?xml version="1.0" encoding="UTF-8"?>
 2 <beans xmlns="http://www.springframework.org/schema/beans"
 3        xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
 4        xmlns:context="http://www.springframework.org/schema/context"
 5        xmlns:aop="http://www.springframework.org/schema/aop" 
 6        xsi:schemaLocation="http://www.springframework.org/schema/beans
 7            http://www.springframework.org/schema/beans/spring-beans-2.5.xsd
 8            http://www.springframework.org/schema/context 
 9            http://www.springframework.org/schema/context/spring-context-2.5.xsd
10            http://www.springframework.org/schema/aop http://www.springframework.org/schema/aop/spring-aop-2.5.xsd ">
11     <aop:aspectj-autoproxy></aop:aspectj-autoproxy>
12     <bean id="personService" class="cn.itcast.service.imp.PersonServiceBean"></bean>
13     <bean id="sapectBean" class="cn.itcast.service.Interceptor"></bean>
14     <aop:config>
15         <aop:aspect id="asp" ref="sapectBean">
16             <aop:pointcut  id="aspCut" expression="execution(* cn.itcast.service.imp.PersonServiceBean.*(..))"/>
17             <aop:before pointcut-ref="aspCut" method="doAcessCheck"/>
18             <aop:after-returning pointcut-ref="aspCut" method="doAccessCheckAfter"/>
19             <aop:after-throwing pointcut-ref="aspCut" method="dofterThrowing"/>
20             <aop:after pointcut-ref="aspCut" method="doAfter"/>
21             <aop:around pointcut-ref="aspCut" method="doAround"/>
22         </aop:aspect>
23     </aop:config>    
24 </beans>

aop

原文地址:https://www.cnblogs.com/fanglove/p/2818489.html