先在说一下什么是Aop。
我们之前在学filter的时候说过一点,当请求进入到servlet的时候,我们进行设置了字符编码以及跨域问题, 那么我们每个servelt都要去写,很麻烦,所以,我们可以利用aop思想,纵向重复,横行抽取。
我们可以在过滤器中配置编码以及解决跨域问题,因为我们设置的过滤器是过滤我们的所有请求。所以在过滤器里面可以设置这些。
那么SpringAop也是如此,我们每次在service时都要打开和提交事务,比较繁琐,那么我们也可以将他抽取出来进行开启和提交,所以说这里要提到一个词,叫做java代理。首先要明确我们学springAop是为了解决什么问题的。
java代理:
举个例子:如果你要找一个明星上综艺节目,其实你应该找的不是明星本人(目标对象),而是他的经纪人(代理对象),你想访问目标对象,必须先通过代理对象,由代理对象决定访问目标对象,java提供了一个Proxy类能够实现代理。
Spring有两种代理:
①动态代理:
代理对象必须实现接口,否则不能实现动态代理
准备一个UserService UserServiceImpl
准备一个获得UserService代理对象的类
1. 获取代理对象,通过调用Proxy的newProxyInstence方法,传递三个参数,第一个参数:类的加载器,第二个参数:代理对象的接口(实现类的接口)第三个参数:this,这样得到了一个代理对象
2. 实现代理对象的方法,让这个类实现InvocationHandler接口,实现它的方法invoke(代理的对象,调用的方法,方法的参数)
3. 被代理的对象方法还是要被调用,所有调用method,invoke()两个参数,一个是被代理对象,参数,给该类加上一个属性被代理对象,并给该类添加构造函数。然后在调用代理对象的方法前后可以加上对应的内容
privateUserService us;
public UserServiceProxyFactory(UserService us) {
this.us = us;
}
public UserService getUserServiceProxy(){//加强版的代理对象
UserService userServiceProxy = (UserService)Proxy.newProxyInstance(UserServiceProxyFactory.class.getClassLoader(), UserServiceImpl.class.getInterfaces(), this);
return userServiceProxy;//返回代理对象
}
@Override
public Object invoke(Object proxy, Method method,Object[] args) throws Throwable {
System.out.println("开启事务");
Object invoke = method.invoke(us, args);//代表着接口中的四个方法调用目标方法
System.out.println("关闭事务");
return invoke;
}
②cglib代理:
(1) 第三方代理技术,任何类都可以实现代理,使用继承的机制实现代理,所以被代理对象不能被final修饰
public UserService getUserServiceProxy(){
Enhancer enhancer = new Enhancer();//帮助我们生成代理对象
enhancer.setSuperclass(UserServiceImpl.class);//设置对谁进行代理
enhancer.setCallback(this);//回调方法调用intercept 会自动执行下面的intercept
UserService userService = (UserService) enhancer.create();
return userService;
}
@Override
public Object intercept(Object o, Method method,Object[] objects, MethodProxy methodProxy) throws Throwable {
System.out.println("cglib开启事务");
Object o1 = methodProxy.invokeSuper(o,objects);
System.out.println("cglib关闭事务");
return o1;
}
③如spring配置如何去写
7个专业名词:
JoinPoint 连接点
PointCut 切入点
Advice 通知
Target 目标对象
Waving 织入
Proxy 代理
Aspect 切面
第一步:导包
1. 准备目标对象UserServiceImpl
2. 准备通知
3. 配置applocationContext.xml文件
4. 导入约束
<bean name="myAdvice" class="cn.hd.springProxy.MyAdvice"></bean>
<bean name="userService"class="cn.hd.springProxy.impl.UserServiceImpl"></bean>
<!--配置aop切入-->
<aop:config>
</aop:config>
5. 直接打入aop:config 如果有提示就直接导入,如果没有提示就手动导入
配置切入:<aop:cinfig></aop:config>
配置切入点:<aop:pointcut id=“”expression=”目标对象要增强的放方法”></aop:pointcut>
配置切面,将通知织入到对应的切入点。
<aop:aspect ref=”通知”>
<aop:before method="before" pointcut-ref="pc"></aop:before> <aop:after method="after" pointcut-ref="pc"></aop:after>
</aop:aspect>