德州网站优化公司,怎样增加网站权重,前端搜索网站引擎怎么做,施工企业税款缴纳提示#xff1a;英语很重要#xff0c;单词是读的#xff0c;是拼出来的#xff0c;和拼音一样 文章目录 前言前期准备1️⃣ DI 依赖注入1、xml 配置方式2、注解方式 annotation❗相关注解Spring中Bean的作用域❗Scope() 注解Qualifier(XXXServiceImpl) 指定哪… 提示英语很重要单词是读的是拼出来的和拼音一样 文章目录 前言前期准备1️⃣ DI 依赖注入1、xml 配置方式2、注解方式 annotation❗相关注解Spring中Bean的作用域❗Scope() 注解Qualifier(XXXServiceImpl) 指定哪个实现类 3、javaConfig方式BeanFactory与ApplicationContext的区别是?❗ 2️⃣ AOP 面向对象一、JDK 动态代理二、Cglib 字节码生成抽取重复代码总结 五种通知类型性能监测案例 前言
提示controller→service→dao互相依赖
Spring容器最大的作用
帮我们管理很多类对象的创建帮我们管理他们对象之间的彼此依赖注入
Spring实现依赖注入有三种方式注解方式官方推荐方式、xml配置文件方式、javaConfig方式。
Spring两大核心 DI依赖注入Dependency Injection AOP面向切面编程Aspect Oriented Programming
Spring框架的优点如下
非侵入式设计最小化应用程序代码对框架的依赖。解耦、简化开发降低组件之间的耦合性。支持AOP提高程序的复用性。支持声明式事务处理方便管理事务。方便程序测试提供对Junit4的支持。方便集成各种优秀框架如Struts、Hibernate、MyBatis、Quartz等。简化Java EE API的使用提供对JDBC、JavaMail等API的封装降低应用难度。 提示以下是本篇文章正文内容下面案例可供参考
前期准备
第一步新建项目Maven项目 在下一步中勾选第一个选项创建一个简单的项目最后填写相关信息后完成 第二步完善 pom.xml 文件
项目建成后在 pom.xml 文件中导入相关代码比如
缺什么加什么 dependencies!-- 此依赖会关联引用Spring中的所有基础jar包 --dependencygroupIdorg.springframework/groupIdartifactIdspring-context/artifactIdversion5.2.8.RELEASE/version/dependencydependencygroupIdorg.aspectj/groupIdartifactIdaspectjweaver/artifactIdversion1.8.7/version/dependencydependencygroupIdjunit/groupIdartifactIdjunit/artifactIdversion4.12/versionscopetest/scope/dependencydependencygroupIdorg.slf4j/groupIdartifactIdslf4j-log4j12/artifactIdversion1.7.15/version/dependencydependencygroupIdlog4j/groupIdartifactIdlog4j/artifactIdversion1.2.17/version/dependency/dependencies第三步配置 main/resources 文件夹
bean.xml 配置文件
?xml version1.0 encodingUTF-8?
beansxmlnshttp://www.springframework.org/schema/beansxmlns:contexthttp://www.springframework.org/schema/contextxmlns:aophttp://www.springframework.org/schema/aopxmlns:xsihttp://www.w3.org/2001/XMLSchema-instancexsi:schemaLocationhttp://www.springframework.org/schema/beanshttp://www.springframework.org/schema/beans/spring-beans.xsdhttp://www.springframework.org/schema/contexthttp://www.springframework.org/schema/context/spring-context.xsdhttp://www.springframework.org/schema/aophttp://www.springframework.org/schema/aop/spring-aop-4.1.xsd/beanslog4j.properties配置文件可以显示 log 输出
### direct log messages to stdout ###
log4j.appender.stdoutorg.apache.log4j.ConsoleAppender
log4j.appender.stdout.TargetSystem.out
log4j.appender.stdout.layoutorg.apache.log4j.PatternLayout
log4j.appender.stdout.layout.ConversionPattern%d{yyyy-MM-dd HH:mm:ss} %m%n
log4j.rootLoggerdebug,stdout第四步接下来新建测试类
package com.spring;import org.junit.Before;
import org.junit.Test;
import org.springframework.context.ApplicationContext;
import org.springframework.context.annotation.AnnotationConfigApplicationContext;
import org.springframework.context.support.ClassPathXmlApplicationContext;public class AppTestUnit
{ApplicationContext context null;Beforepublic void before() throws Exception {// xml配置文件方式实现 配置文件的路径context new ClassPathXmlApplicationContext(bean.xml);// 注解方式实现包名被更改时这里对应的包名也要改//context new AnnotationConfigApplicationContext(com.spring);}Test public void test() {}}1️⃣ DI 依赖注入
原来是叫 IOCSpring 的Bean中主要包含三种装配方式
依赖注入的原理 将对象的依赖关系从代码中移除而是通过外部容器来管理这些依赖关系将某一个需要的依赖右容器注入
1、xml 配置方式 大致过程 dao接口和实现类、配置xml、测试service接口和实现类、配置xml、测试controller直接写类、配置xml、测试
在main/java文件夹下新建包com.spring.xml然后在下面新建dao、service、controller包
dao 包下新建接口这里以 Goods 商品 取名
在里面加上一个方法
public interface GoodsDao{void insertGoods();
}紧接着着这个包下创建一个同名Impl的实现类
项目创建好后在实现类后面跟上implements要实现的接口名然后保存添加未实现的方法 在里面加一句输出代表执行了 Overridepublic void insertGoods() {System.out.println(成功向MySQL数据库中增加一行商品数据);}接下来需要在bean.xml文件中进行一个配置因为 dao 类对象要容器创建
!-- 在xml中进行配置配置好的类的对象创建 就由spring容器负责 -- !-- 实现类创建对象 --
bean idgoodsdao classcom.spring.xml.dao.GoodsDaoImpl/bean
!-- iddao包接口名 class实现类的限定名 --测试代码传名字 getBean后的值是刚才在bean.xml中配置的id值 goodsdao然后加强转有一个向下的转型 Test public void test() {// 从容器context中获得getBean使用的对象GoodsDaoImpl dao (GoodsDaoImpl) context.getBean(goodsdao);dao.insertGoods(); }测试运行
getBean还有另一个重载的方法传类的信息常用
两种实现方法结果一致 Test public void test() {// 从容器context中获得getBean使用的对象
// GoodsDaoImpl dao (GoodsDaoImpl) context.getBean(goodsdao);GoodsDaoImpl dao context.getBean(GoodsDaoImpl.class);dao.insertGoods(); }接下来写 service 包在里面写个接口
public interface GoodsService {void addGoods();
}再写一个实现类与 service 包接口同名Impl 第一步添加未实现的方法 第二步定义 dao 类型的变量体现业务依赖 dao 第三步加set方法只有xml和javaConfig需要 XyzServiceImpl 代码
public class GoodsServiceImpl implements GoodsService{//2、添加dao类型的变量体现业务依赖daoprivate GoodsDao dao;// 完成需要的dao对象的注入public void setDao(GoodsDao dao) {this.dao dao;}// 3、加set方法只有xml和javaConfig需要Overridepublic void addGoods() { // 1、添加未实现的方法 // 4、输出System.out.println(商品业务——addGoods);// 业务类调 daodao.insertGoods();}
}现在ServiceImpl 实现类写完了因为业务类对象也要容器创建所以接下来在bean.xml内加上容器
property标记代表所需依赖注入的配置
property 中的 name 属性名指的是ServiceImpl 实现类中添加dao类型的变量
property 中的 ref 属性指的是要注入的对象 id
!-- id小写service包接口名 class实现类的限定名 --
bean idgoodsservice classcom.springtest.service.GoodsServiceImpl
!-- service需要dao注入进来property标记代表所需依赖注入的配置--
property namedao refgoodsdao/property
/bean回到测试类写service测试先注释或删掉dao的测试 Test public void test() {// 从容器context中获得getBean使用的对象
// GoodsDaoImpl dao (GoodsDaoImpl) context.getBean(goodsdao);
// GoodsDaoImpl dao context.getBean(GoodsDaoImpl.class);
// dao.insertGoods(); GoodsServiceImpl service context.getBean(GoodsServiceImpl.class);// 证明依赖注入成功调service方法时dao的方法也输出了service.addGoods();}最后写controller
public class GoodsController {// 2.增加接口体现依赖private GoodsService service;// 3.生成set方法public void setService(GoodsService service) {this.service service;}
// 1.doGet()public void doGet() {System.out.println(获取请求数据);// 4.调用service方法service.addGoods();System.out.println(生成相应);}
}接下来写controller的bean.xml配置
!-- id小写controller类名 classController类的限定名 --
bean idgoodscontroller classcom.springtest.controller.GoodsController
property nameservice refgoodsservice/property
/beancontroller测试先注释或删掉 dao 和 service 的测试 Test public void test() {// 从容器context中获得getBean使用的对象
// GoodsDaoImpl dao (GoodsDaoImpl) context.getBean(goodsdao);
// GoodsDaoImpl dao context.getBean(GoodsDaoImpl.class);
// dao.insertGoods(); // GoodsServiceImpl service context.getBean(GoodsServiceImpl.class);
// // 证明依赖注入成功调service方法时dao的方法也输出了
// service.addGoods();GoodsController controller context.getBean(GoodsController.class);controller.doGet();}2、注解方式 annotation❗ 注解 依赖创建对象Component通用依赖注入注解Autowired
在main/java文件夹下新建包com.spring.annotation然后在下面新建dao、service、controller包
先在dao包下新建接口和接口的实现类这里取名 business
接口代码
public interface BusinessDao {void updateBusiness();
}接口的实现类
// 注解功能等同于xml中的bean标记 abc是自定义名字
Component
public class BusinessDaoImpl implements BusinessDao{Overridepublic void updateBusiness() {// 添加未实现的方法System.out.println(修改商家数据);}}测试代码
import org.junit.Before;
import org.junit.Test;
import org.springframework.context.ApplicationContext;
import org.springframework.context.annotation.AnnotationConfigApplicationContext;public class AppTestAnnotation
{ApplicationContext context null;Beforepublic void before() throws Exception {
// 这里配置的包名当包名被改变时这里也需要被改变context new AnnotationConfigApplicationContext(com.spring);// 创建注解容器时需要指定扫描的包名// 那么容器创建时会自动的扫描这个包以及子包中的所有类// 找有Component注解的类}Test public void test() {}
}接下来写注解Test 的内容看数据能否被取出 Test public void test() {BusinessDaoImpl dao context.getBean(BusinessDaoImpl.class);dao.updateBusiness();}在BusinessDaoImpl实现类的注解中可以加上自定义名字Component(abc)
接下来在service中新建接口以及接口对应的实现类
接口代码
public interface BusinessService {void update();
}接口对应的实现类
// 3.添加注解
Component
public class BusinessServiceImpl implements BusinessService{// 4.自定装配实现依赖注入Autowired // 2.增加dao类型的属性接口private BusinessDao dao;Overridepublic void update() {// 1.添加未实现的方法// 5.输出 调用依赖dao的方法System.out.println(修改业务);dao.updateBusiness();}}在测试类中写service测试先注释或删掉掉dao的测试 Test public void test() {BusinessServiceImpl service context.getBean(BusinessServiceImpl.class);service.update();}接下来在controller包中新建controller类
Component // 2.加注解
public class BusinessController {Autowired // 3.依赖注入注解 自动装配private BusinessService service; // 1.加依赖的属性接口// 4.加方法public void doPost() {System.out.println(获取请求数据);service.update();System.out.println(生成响应);}}测试类测试 Test public void test() {BusinessController controller context.getBean(BusinessController.class);controller.doPost();}相关注解
上面案例说了两个注解
依赖创建对象Component通用依赖注入注解Autowired
下面还有三个注解这三个注解功能一样但更有语义化
将一个类声明为Spring容器管理的bean的注解有
Component通用的注解可标注任意类为 Spring 组件。如果一个Bean不知道属于哪个层可以使用
Repository对应数据层即 Dao 层主要用于数据库相关操作。整合mybatis时用 Mapper
Service对应服务层主要涉及一些复杂的逻辑需要用到 Dao层。
Controller对应 Spring MVC控制层主要用户接受用户请求并调用 Service 层返回数据给前端页面。
如果把上面案例中的 dao 层中的 Component 注解换为Repository service 中的 Component 注解换为Service controller 中的 Component 注解换为Controller
那么测试输出一样也就是说
Spring中Bean的作用域❗
Spring中Bean的作用域及各自意义
Scope() 注解设置Bean的作用域。值如下
作用域说明singleton单例模式在整个Spring IoC容器中使用singleton定义的Bean将只有一个实例prototype原型模式每次通过容器的getBean方法获取prototype定义的Bean时都将产生一个新的Bean实例request对于每次HTTP请求使用request定义的Bean都将产生一个新实例即每次HTTP请求将会产生不同的Bean实例。只有在Web应用中使用Spring时该作用域才有效session对于每次HTTP Session使用session定义的Bean豆浆产生一个新实例。同样只有在Web应用中使用Spring时该作用域才有效globalsession每个全局的HTTP Session使用session定义的Bean都将产生一个新实例。典型情况下仅在使用portlet context的时候有效。同样只有在Web应用中使用Spring时该作用域才有效
Scope() 注解
在累的前面加上Scope()
Component
Scope(prototype) //每次都是一个新对象
public class Hello {}测试代码默认应该是单例 Test public void test() {// 为了测试每次取出的都是同一个对象for(int i0; i10;i) {Hello s context.getBean(Hello.class);System.out.println(s);} }输出信息
Qualifier(“XXXServiceImpl”) 指定哪个实现类
在service包中新建实现类BusinessServiceImpl1让他也实现BusinessService接口
Service
public class BusinessServiceImpl1 implements BusinessService{Overridepublic void update() {// TODO 自动生成的方法存根System.out.println(asdfg);}}现在有两个实现类对象存在
测试类代码执行 Test public void test() {BusinessController controller context.getBean(BusinessController.class);controller.doPost(); }报错信息
Caused by: org.springframework.beans.factory.NoUniqueBeanDefinitionException: No qualifying bean of type com.spring.annotation.service.BusinessService available: expected single matching bean but found 2: businessServiceImpl,businessServiceImpl1at org.springframework.beans.factory.config.DependencyDescriptor.resolveNotUnique(DependencyDescriptor.java:220)at org.springframework.beans.factory.support.DefaultListableBeanFactory.doResolveDependency(DefaultListableBeanFactory.java:1285)at org.springframework.beans.factory.support.DefaultListableBeanFactory.resolveDependency(DefaultListableBeanFactory.java:1227)at org.springframework.beans.factory.annotation.AutowiredAnnotationBeanPostProcessor$AutowiredFieldElement.inject(AutowiredAnnotationBeanPostProcessor.java:640)... 37 more原因期望一个匹配对象但是现在有两个businessServiceImpl和businessServiceImpl1
在BusinessController 类中加一个Qualifier注解让他指定哪个实现类 输出结果
3、javaConfig方式
在项目初期时会做一些项目配置某个类不是我们能更改的代码但是这个类还需要容器管理对象的时候加 javaConfigjavaconfig方式必须给配置类增加Configuration注解 在main/java文件夹下新建包com.spring.javaconfig然后在下面新建dao、service包
dao 包下新建接口及同名的接口Impl实现类
接口中代码
public interface UserDao {void query();
}实现类代码
public class UserDaoImpl implements UserDao{Overridepublic void query() {// TODO 自动生成的方法存根System.out.println(查询用户数据);}}在com.spring.javaconfig 包下新建类 AppConfig里面暂时放 dao 的方法
Configuration // javaconfig方式必须给配置类增加此注解
public class AppConfig {Bean // 有Bean注解的方法它返回的对象就会交由spring容器管理public UserDaoImpl dao() {return new UserDaoImpl();}}测试类 Test public void test() {UserDaoImpl dao context.getBean(UserDaoImpl.class);dao.query();}新建service接口及其实现类
接口代码
public interface UserService {void query();
}接口实现类
public class UserServiceImpl implements UserService{// Service依赖Daoprivate UserDao dao;public void setDao(UserDao dao) {// set方法单独生成this.dao dao;}Overridepublic void query() {// TODO 自动生成的方法存根System.out.println(查询用户业务);dao.query();}}在AppConfig 类里面再加一个service方法
Bean// 可以接口/实现类public UserService service(UserDao dao) {UserServiceImpl service new UserServiceImpl();service.setDao(dao);return service;}测试代码 Test public void test() {UserServiceImpl service context.getBean(UserServiceImpl.class);service.query();}BeanFactory与ApplicationContext的区别是?❗
BeanFactory Bean工厂org.springframework.beans.factory.BeanFactory是Spring框架最核心的接口提供了IoC的配置机制使管理不同类型的Java对象成为可能。特点是采用延迟加载Bean直到第一次使用Bean实例时才会创建Bean。
ApplicationContext 应用上下文org.springframework.context.ApplicationContext继承自BeanFactory提供了更多面向应用的功能比如国际化支持、框架事件体系更易于创建实际应用。
2️⃣ AOP 面向对象
简单的说它就是把我们程序重复的代码抽取出来 在需要执行的时候使用动态代理的技术在不修改源码的基础上对我们的已有方法进行增强。
应用场景记录日志、监控方法运行时间 监控性能、权限控制、缓存优化 、事务管理
AOP 内注解 Pointcut定义切点指定在哪些方法或类上应用增强。
Before在目标方法执行之前执行增强。
AfterReturning在目标方法正常返回后执行增强。
AfterThrowing在目标方法抛出异常后执行增强。
Around在目标方法执行前后执行增强。
DeclareParents为被切入对象引入新的接口和实现类。
两种AOP实现方案JDK 动态代理、Cglib 字节码生成
一、JDK 动态代理
运用方式
在使用JDK动态代理时需要实现InvocationHandler接口并在方法中实现代理逻辑同时利用Proxy类生成代理对象。下面是一个简单的实现示例
public interface HelloWorld {void sayHello();
}public class HelloWorldImpl implements HelloWorld {Overridepublic void sayHello() {System.out.println(Hello World!);}
}public class MyInvocationHandler implements InvocationHandler {private Object target;public MyInvocationHandler(Object target) {this.target target;}Overridepublic Object invoke(Object proxy, Method method, Object[] args) throws Throwable {System.out.println(Before method: method.getName());Object result method.invoke(target, args);System.out.println(After method: method.getName());return result;}
}public class Main {public static void main(String[] args) {HelloWorld helloWorld new HelloWorldImpl();MyInvocationHandler handler new MyInvocationHandler(helloWorld);HelloWorld proxyInstance (HelloWorld) Proxy.newProxyInstance(helloWorld.getClass().getClassLoader(),helloWorld.getClass().getInterfaces(), handler);proxyInstance.sayHello();}
}何时使用
JDK动态代理适用于对实现了接口的对象进行代理它的运行时效率相对较高、实现较为简单适用于大部分场景下的对象代理。
适用场景
对实现了接口的对象进行代理需要在运行时动态生成代理类对于单继承模型较为适用。
优缺点
JDK动态代理的优势在于
运行时效率相对较高实现较为简单。
缺点在于
只能代理实现了接口的对象。
二、Cglib 字节码生成
运用方式
在使用Cglib字节码生成时需要引入Cglib的依赖继承MethodInterceptor接口并在方法中实现代理逻辑。下面是一个简单的实现示例
public interface HelloWorld {void sayHello();
}public class HelloWorldImpl {public void sayHello() {System.out.println(Hello World!);}
}public class MyMethodInterceptor implements MethodInterceptor {Overridepublic Object intercept(Object o, Method method, Object[] objects, MethodProxy methodProxy) throws Throwable {System.out.println(Before method: method.getName());Object result methodProxy.invokeSuper(o, objects);System.out.println(After method: method.getName());return result;}
}public class Main {public static void main(String[] args) {Enhancer enhancer new Enhancer();enhancer.setSuperclass(HelloWorldImpl.class);enhancer.setCallback(new MyMethodInterceptor());HelloWorldImpl proxy (HelloWorldImpl) enhancer.create();proxy.sayHello();}
}何时使用
Cglib 字节码生成适用于对未实现接口的对象进行代理代理逻辑灵活适用于复杂逻辑下的对象代理。
适用场景
对未实现接口的对象进行代理需要在运行时动态生成代理类对于单继承模型较为适用。
优缺点
Cglib 字节码生成的优势在于
代理逻辑的灵活性可以代理未实现接口的对象。
缺点在于
运行时效率相对较低实现复杂。
三、JDK 动态代理和 Cglib 字节码生成的比较
JDK动态代理和Cglib字节码生成都是Java中常用的实现动态代理的方式它们各自之间的优缺点如下
JDK动态代理的优点在于运行时效率相对较高、实现较为简单缺点在于只能代理实现了接口的对象。
Cglib字节码生成的优点在于代理逻辑的灵活性可以代理未实现接口的对象缺点在于运行时效率相对较低、实现复杂。
在使用 JDK动态代理和Cglib字节码生成时需要根据具体对象的特点及使用场景来决定使用哪种方式。对于实现了接口的对象可以优先考虑使用JDK动态代理因为它的运行时效率相对较高、实现较为简单对于未实现接口的对象可以优先考虑使用Cglib字节码生成因为它代理逻辑灵活可以代理未实现接口的对象。 抽取重复代码
AOP核心思想把重复的代码从方法中抽取出来
在main/java文件夹下新建包com.spring.aop然后在下面新建aop、service包
先在service包内增加代码创建接口及其实现类
public interface FoodService {void insert();void delete();
}实现类代码在开始执行前的输出视为重复代码
Service
public class FoodServiceImpl implements FoodService{Overridepublic void insert() {// 添加未实现的方法System.out.println(insert方法开始执行);// 模拟调用dao层代码System.out.println(增加业务代码);}Overridepublic void delete() {// 添加未实现的方法System.out.println(delete方法开始执行);// 模拟调用dao层代码System.out.println(删除业务代码);}}测试代码 Test public void test() {FoodServiceImpl service context.getBean(FoodServiceImpl.class);service.insert();service.delete();}因为方法中有重复代码这时候适用于AOP接下来定义一个切面代码
在aop包内新建类MyAspect并把之前的重复代码注释或删掉
//基本语法
Component
Aspect // 方面 切面
EnableAspectJAutoProxy //开启切面动态代理
public class MyAspect {// 切入点 配置的是切入执行的方法信息 execution是函数后面加(),如果包名改变这里也需要改Pointcut(execution(* com.spring.serve.*.*(..)))// 第一个*所切入执行方法的返回值类型这里不区分返回值类型这个方法所在的类的信息完整的限定名// 第二个*切入到serve包所有类的方法// 第三个*切入到哪些方法// (..)方法中的所有参数public void pt() {}// 抽取出来的重复代码封装到方面中的一个通知把之前的重复代码注释或删掉// 通知抽取方法Before(pt()) //通知和切入点的联系public void before(JoinPoint jp) {// JoinPoint 连接点代表aop切入的方法信息String methodName jp.getSignature().getName();System.out.println(methodName业务开始执行);}
}测试类代码 因为他会动态生成一个新的类所以更改测试代码改接口 Test public void test() {FoodService service context.getBean(FoodService.class);service.insert();service.delete();}总结
一、定义一个切面/方面类
二、增加两种类型的方法
通知抽取出来的方法信息重读代码加注解Before(xxx()) 定义切入点的方法
三、AOP中的切入点
// 切入点 配置的是切入执行的方法信息 execution是函数后面加(),如果包名改变这里也需要改Pointcut(execution(* com.spring.serve.*.*(..)))// 第一个*所切入执行方法的返回值类型这里不区分返回值类型这个方法所在的类的信息完整的限定名// 第二个*切入到serve包所有类的方法// 第三个*切入到哪些方法这里是所有方法// (..)方法中的所有参数接下来在通知的方法中加一个参数从参数里面拿到切入方法的相关信息 public void pt() {}// 抽取出来的重复代码封装到方面中的一个通知把之前的重复代码注释或删掉// 通知抽取方法Before(pt()) //通知和切入点的联系public void before(JoinPoint jp) {// JoinPoint 连接点代表aop切入的方法信息String methodName jp.getSignature().getName();System.out.println(methodName业务开始执行);}
}五种通知类型
方面代码一般也称为通知定义一个“切面”要实现的功能。通知有五种
前置通知Before在某连接点JoinPoint 就是要织入的业务方法之前执行的通知。后置通知After当某连接点退出时执行的通知不论是正常结束还是发生异常。返回通知AfterReturning最终通知在这里可以得到业务方法的返回值。但在发生异常时无法得到返回值。环绕通知Around包围一个连接点的通知也就是在业务方法执行前和执行后执行的通知。异常通知AfterThrowing在业务方法发生异常时执行的通知。
后置通知 After(pt())public void after() {System.out.println(后置通知执行了);}测试输出后在最后面输出了——后置通知执行了
返回通知 AfterReturning(pt())public void afterReturn() {System.out.println(返回通知执行了);}在service接口文件中给他加一个带返回值的方法
int update();然后在service接口实现类中添加方法 Overridepublic int update() {// TODO 自动生成的方法存根System.out.println(修改业务);return 0;}在测试类中加上修改方法并注释掉之前的方法因为没有返回值 Test public void test() {FoodService service context.getBean(FoodService.class);
// service.insert();
// service.delete();service.update();}让他发生异常就不会执行了 Overridepublic int update() {// TODO 自动生成的方法存根System.out.println(修改业务);String string null;string.length();return 0;}发生空指针异常
接下来还是在MyAspect类中写异常通知 AfterThrowing(pt())public void AfterThrowingException() {System.out.println(异常通知执行了);}把前面长度length那一行注释掉再运行修改业务输出
环绕通知
Around(pt()) public Object around(ProceedingJoinPoint jp) {System.out.println(环绕通知--1执行了);Object object null;// 切入的方法执行try {object jp.proceed();} catch (Throwable e) {// TODO 自动生成的 catch 块e.printStackTrace();}System.out.println(环绕通知--2执行了);return object;}性能监测案例
Component
Aspect
EnableAspectJAutoProxy
public class PerformanceAspect {Pointcut(execution(* com.spring.serve.*.*(..)))public void cut() {}Around(cut())public Object executedTime(ProceedingJoinPoint jp) {long begin System.currentTimeMillis();Object object null;try {object jp.proceed();} catch (Throwable e) {// TODO 自动生成的 catch 块e.printStackTrace();}long end System.currentTimeMillis();String methodName jp.getSignature().getName();System.out.println(methodName方法执行共花费(end-begin)毫秒);return object;}
}测试运行后 Test public void test() {FoodService service context.getBean(FoodService.class);service.update();}因为方法很小执行时间很短所有看不出来
接下来在接口实现类中改造update方法人为加个休眠
Overridepublic int update() {// TODO 自动生成的方法存根System.out.println(修改业务);String string null;//string.length();try {// 随机数Thread.sleep(new Random().nextInt(1000));} catch (InterruptedException e) {// TODO 自动生成的 catch 块e.printStackTrace();}return 0;}再次运行