热门标签 | HotTags
当前位置:  开发笔记 > 编程语言 > 正文

开发笔记:Spring基础3

篇首语:本文由编程笔记#小编为大家整理,主要介绍了Spring基础3相关的知识,希望对你有一定的参考价值。一、AOP1)AOP简介

篇首语:本文由编程笔记#小编为大家整理,主要介绍了Spring基础3相关的知识,希望对你有一定的参考价值。



一、AOP

  1)AOP简介:

    Aspect Oriented Programming,面向切面编程

    通过预编译方式和动态代理实现程序功能的一种技术,AOP是OOP的延续,是函数式编程的一种衍生范例。利用AOP可以对业务逻辑各个部分进行隔离,从而使得业务逻辑之间的耦合度降低,提高程序的可重用性,同时提高开发效率。

    AOP采用横向抽取机制取代了传统纵向继承,不破坏原有的类,生成一个动态代理类,在原有类的基础上进行增强,可以随时添加,随时取消功能。

    Spring中使用的AOP是Aspectj

二、动态代理

  1)JDK动态代理,依赖接口

      

    


package com.ual.dao;
public class GoodsDaoImpl implements GoodsDao {
@Override
public void save() {
System.out.println(
"保存");
}
@Override
public void update() {
System.out.println(
"更新");
}
}


package com.ual.Proxy;
import com.ual.dao.GoodsDao;
import java.lang.reflect.InvocationHandler;
import java.lang.reflect.Method;
import java.lang.reflect.Proxy;
public class GoodsJDKProxy {
public GoodsDao createProxy(GoodsDao goodsDao) {
GoodsDao goodsDaoProxy
= (GoodsDao) Proxy.newProxyInstance(goodsDao.getClass().getClassLoader(),
goodsDao.getClass().getInterfaces(),
new InvocationHandler() {
@Override
//当调用对象的时候,所有的方法都会来到这里
public Object invoke(Object proxy, Method method, Object[] args) throws Throwable {
if("save".equals(method.getName())){
System.out.println(
"保存校验");
return method.invoke(goodsDao, args);//返回的代理对象
}
if("update".equals(method.getName())){
System.out.println(
"更新校验");//方法执行之前,执行
GoodsDao goodsDao1 = (GoodsDao)method.invoke(goodsDao, args);//返回的代理对象
System.out.println("日志打印");//方法执行之后
return goodsDao1;
}
return method.invoke(goodsDao, args);//返回的代理对象
}
});
return goodsDaoProxy;//返回一个代理对象,代理对象中的方法执行时,会回调匿名内部类中的Invoke方法。
}
}


package com.ual.test;
import com.ual.Proxy.GoodsJDKProxy;
import com.ual.dao.GoodsDao;
import com.ual.dao.GoodsDaoImpl;
import org.junit.Test;
public class GoodsDaoTest {
@Test
public void test() {
GoodsDao goodsDao
= new GoodsDaoImpl();
/* goodsDao.save();*/
GoodsJDKProxy goodsJDKProxy
= new GoodsJDKProxy();
GoodsDao proxy
= goodsJDKProxy.createProxy(goodsDao);
proxy.save();
proxy.update();
}
}

  2)cglib动态代理,不需要依赖接口,核心是通过子类继承

  Spring会在jdk与cglib之间进行自动切换,有接口使用jdk,没有接口使用cglib。

  

三、AOP相关术语

1)JoinPoint:连接点,可以被拦截的方法,能够(可以)被增强的方法,称为连接点。

2)Pointcut:切入点,真正被拦截,增强的方法

3)Advice:通知,增加的内容,通常封装成一个方法,这个方法称之为通知

4)Introduction:引介,类层面的增强,给原有类添加一些新的属性和方法。在开发中通常给方法加强

5)Target:被增强的对象

6)Weaving:织入,将通知应用到目标对象的过程

7)Proxy:代理对象

8)Aspect:切面,多个通知和对各切入点的集合

四、Spring 中AOP的使用

1)引入Spring基本jar包

2)引入AOP开发相关jar包

3)配置文件引入AOP约束

4)Spring 测试

引入这个jar包,这样就不用每次都获取工厂

在测试类上添加


package com.ual.test;
import com.ual.service.UserService;
import org.junit.Test;
import org.junit.runner.RunWith;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.test.context.ContextConfiguration;
import org.springframework.test.context.junit4.SpringJUnit4ClassRunner;
@RunWith(SpringJUnit4ClassRunner.
class)
@ContextConfiguration(
"classpath:applicationContext.xml")
public class UserTest {
@Autowired
private UserService userService;
@Test
public void test() {
this.userService.delete();
}
}

5)编写一个切面类

 即里面写入通知


package com.ual2.demo;
public class Myaspect {
public void check(){
System.out.println(
"校验");
}
}

6)将切面类交给Spring 

7)配置AOP完成对目标产生代理


<bean id="myaspect" class="com.ual2.demo.Myaspect">bean>

<aop:config>

<aop:pointcut id="pointDelete" expression="execution(* com.ual.dao.UserDaoImpl.delete(..))"/>

<aop:aspect ref="myaspect">
<aop:before method="check" pointcut-ref="pointDelete"/>
aop:aspect>
aop:config>
beans>

五、AOP通知类型

1)前置通知

  在目标方法执行之前执行

2)后置通知

  在目标方法执行之后执行,可以在通知中可以得到一个目标方法的返回值

3)环绕通知

在目标方法执行之前,执行之后操作

4)异常抛出通知

在程序出现异常时才会触发

5)最终通知

无论代码是否有异常,都会执行

六、AOP切入点表达式

基于execution函数完成

【访问修饰符(可选)】 方法返回值(*代表任意类型)包名.类名.方法名(参数)

参数:“..”为任意类型;包名.类名+.方法名(参数)当前类和子类该方法都为切入点

   * com.ual..*.*(..):com.ual包以及子包下面的所有类的所有方法都是切入点

七、AOP中的注解开发

1)引入jar包

2)引入配置文件

3)编写切面类配置

 4)使用注解的AOP对象对目标类进行增强

  1.在配置文件中开启以注解形式进行AOP开发

  2.在切面类上添加注解

  

  3.测试方法

5)注解AOP通知类型

1.@Before:前置通知

2.@AfterReturenning:后置通知

  2.1 没有返回值

 

  2.2 有返回值

 

3.@Around环绕通知 

4.@AfterThrowing异常抛出通知

  4.1没有获取异常信息

  4.2获取异常信息

5.@After:最终通知  

6.同一通知应用多个方法

也可以用这种方式

注意:当使用接口时与不使用接口时,Spring内部代理区别:

  1.使用接口,采用jdk动态代理

  2.不使用接口,采用cglib动态代理



推荐阅读
author-avatar
feng2502863897
这个家伙很懒,什么也没留下!
PHP1.CN | 中国最专业的PHP中文社区 | DevBox开发工具箱 | json解析格式化 |PHP资讯 | PHP教程 | 数据库技术 | 服务器技术 | 前端开发技术 | PHP框架 | 开发工具 | 在线工具
Copyright © 1998 - 2020 PHP1.CN. All Rights Reserved | 京公网安备 11010802041100号 | 京ICP备19059560号-4 | PHP1.CN 第一PHP社区 版权所有