您的位置:首页 > 财经 > 金融 > 婚庆网站搭建的流程_爱站查询_怎么网站推广_百度安装到桌面

婚庆网站搭建的流程_爱站查询_怎么网站推广_百度安装到桌面

2024/11/17 23:34:33 来源:https://blog.csdn.net/qq_73700396/article/details/142726766  浏览:    关键词:婚庆网站搭建的流程_爱站查询_怎么网站推广_百度安装到桌面
婚庆网站搭建的流程_爱站查询_怎么网站推广_百度安装到桌面

前面介绍了这么多种通知类型,具体该选哪一种呢?

我们可以通过一些案例加深下对通知类型的学习。

34-案例:利用AOP环绕通知计算业务层接口执行效率

需求分析

这个需求也比较简单,前面我们在介绍AOP的时候已经演示过:

  • 需求:任意业务层接口执行均可显示其执行效率(执行时长)
    这个案例的目的是查看每个业务层执行的时间,这样就可以监控出哪个业务比较耗时,将其查找出来方便优化

具体实现的思路:

  1. 开始执行方法之前记录一个时间
  2. 执行方法
  3. 执行完方法之后记录一个时间
  4. 用后一个时间减去前一个时间的差值,就是我们需要的结果

所以要在方法执行的前后添加业务,经过分析我们将采用环绕通知。
说明:原始方法如果只执行一次,时间太快,两个时间差可能为0,所以我们要执行万次来计算时间差。

环境准备

  • 创建一个Maven项目
  • pom.xml添加Spring依赖
<dependency><groupId>org.springframework</groupId><artifactId>spring-context</artifactId><version>5.2.10.RELEASE</version>
</dependency>
<dependency><groupId>org.springframework</groupId><artifactId>spring-jdbc</artifactId><version>5.2.10.RELEASE</version>
</dependency>
<dependency><groupId>org.springframework</groupId><artifactId>spring-test</artifactId><version>5.2.10.RELEASE</version>
</dependency>
<dependency><groupId>org.aspectj</groupId><artifactId>aspectjweaver</artifactId><version>1.9.4</version>
</dependency>
<dependency><groupId>mysql</groupId><artifactId>mysql-connector-java</artifactId><version>8.0.33</version>
</dependency>
<dependency><groupId>com.alibaba</groupId><artifactId>druid</artifactId><version>1.1.16</version>
</dependency>
<dependency><groupId>org.mybatis</groupId><artifactId>mybatis</artifactId><version>3.5.6</version>
</dependency>
<dependency><groupId>org.mybatis</groupId><artifactId>mybatis-spring</artifactId><version>1.3.0</version>
</dependency>
<dependency><groupId>junit</groupId><artifactId>junit</artifactId><version>4.12</version><scope>test</scope>
</dependency>
  • 创建数据库与表
create database spring_db character set utf8;
use spring_db;
create table tbl_account(id int primary key auto_increment,name varchar(35),money double
);INSERT INTO tbl_account(`name`,money) VALUES
('Tom',2800),
('Jerry',3000),
('Jhon',3100);
  • 添加Account、AccountDao、AccountService、AccountServiceImpl类
public class Account {private Integer id;private String name;private Double money;public Account() {}public Account(Integer id, String name, Double money) {this.id = id;this.name = name;this.money = money;}public Integer getId() {return id;}public String getName() {return name;}public Double getMoney() {return money;}public void setId(Integer id) {this.id = id;}public void setName(String name) {this.name = name;}public void setMoney(Double money) {this.money = money;}@Overridepublic String toString() {return "Account{" +"id=" + id +", name='" + name + '\'' +", money=" + money +'}';}
}
public interface AccountDao {@Insert("insert into tbl_account(`name`,money) values(#{name},#{money}) ")void save(Account account);@Delete("delete from tbl_account where id=#{id}")void delete(Integer id);@Update("update tbl_account set `name`=#{name},money=#{money}")void update(Account account);@Select("select * from tbl_account")List<Account> findAll();@Select("select * from tbl_account where id=#{id}")Account findById(Integer id);
}
public interface AccountService {void save(Account account);void update(Account account);void delete(Integer id);List<Account> findAll();Account findById(Integer id);
}
@Service
public class AccountServiceImpl implements AccountService {@Autowiredprivate AccountDao accountDao;@Overridepublic void save(Account account) {accountDao.save(account);}@Overridepublic void update(Account account) {accountDao.update(account);}@Overridepublic void delete(Integer id) {accountDao.delete(id);}@Overridepublic List<Account> findAll() {return accountDao.findAll();}@Overridepublic Account findById(Integer id) {return accountDao.findById(id);}
}
  • resources下提供一个jdbc.properties
jdbc.driver=com.mysql.cj.jdbc.Driver
jdbc.url=jdbc:mysql://localhost:3306/spring_db?useSSL=false
jdbc.username=root
jdbc.password=password
  • 创建相关配置类
public class JdbcConfig {@Value("${jdbc.driver}")private String driver;@Value("${jdbc.url}")private String url;@Value("${jdbc.username}")private String username;@Value("${jdbc.password}")private String password;@Beanpublic DataSource dataSource() {DruidDataSource dataSource = new DruidDataSource();dataSource.setDriverClassName(driver);dataSource.setUrl(url);dataSource.setUsername(username);dataSource.setPassword(password);return dataSource;}
}
public class MyBatisConfig {@Beanpublic SqlSessionFactoryBean sqlSessionFactoryBean(DataSource dataSource) {SqlSessionFactoryBean sqlSessionFactoryBean = new SqlSessionFactoryBean();sqlSessionFactoryBean.setTypeAliasesPackage("com.yolo.pojo");sqlSessionFactoryBean.setDataSource(dataSource);return sqlSessionFactoryBean;}@Beanpublic MapperScannerConfigurer mapperScannerConfigurer() {MapperScannerConfigurer mapperScannerConfigurer = new MapperScannerConfigurer();mapperScannerConfigurer.setBasePackage("com.yolo.dao");return mapperScannerConfigurer;}
}
  • 第一个方法sqlSessionFactoryBean接受一个DataSource类型的参数,创建了一个SqlSessionFactoryBean对象。这个对象设置了类型别名包为 “com.yolo.pojo”,并设置了数据源dataSource。
    这个方法的目的是创建并配置 MyBatis的SqlSessionFactoryBean,它是 MyBatis 和 Spring 集成的关键组件之一,用于创建SqlSession,从而执行数据库操作。
  • 第二个方法mapperScannerConfigurer创建了一个MapperScannerConfigurer对象,并设置了基础包为 “com.yolo.dao”。这个对象用于扫描指定包下的 MyBatis Mapper 接口,并将它们注册到 Spring 容器中,使得这些 Mapper 接口可以被自动注入到其他组件中,方便进行数据库操作。
@Configuration
@ComponentScan("com.yolo")
@PropertySource("classpath:jdbc.properties")
@Import({JdbcConfig.class,MyBatisConfig.class})
public class SpringConfig {
}
  • 编写Spring整合Junit的测试类
@RunWith(SpringJUnit4ClassRunner.class)
@ContextConfiguration(classes = SpringConfig.class)
public class AccountServiceTestCase {@Autowiredprivate AccountService accountService;@Testpublic void testFindById() {Account byId = accountService.findById(2);System.out.println(byId);}@Testpublic void testFindAll(){List<Account> accountList = accountService.findAll();System.out.println(accountList);}
}

运行测试类,结果如下
在这里插入图片描述
在这里插入图片描述

功能开发

  • 步骤一:开启SpringAOP的注解功能
    在Spring的主配置文件SpringConfig类中添加注解
@EnableAspectJAutoProxy
  • 步骤二:创建AOP的通知类
    • 该类要被Spring管理,需要添加@Component
    • 要标识该类是一个AOP的切面类,需要添加@Aspect
    • 配置切入点表达式,需要添加一个方法,并添加@Pointcut
@Component
@Aspect
public class ProjectAdvice {@Pointcut("execution(* com.yolo.service.*Service(..))")public void servicePt() {}public void runSpeed() {}
}
  • 步骤三:添加环绕通知
    在runSpeed()方法上添加@Around
@Component
@Aspect
public class ProjectAdvice {@Pointcut("execution(* com.yolo.service.*Service.*(..))")public void servicePt() {}@Around("servicePt()")public void runSpeed(ProceedingJoinPoint point) {}    
}
  • 步骤四:完成核心业务,记录万次执行的时间
@Component
@Aspect
public class ProjectAdvice {//匹配业务层的所有方法@Pointcut("execution(* com.yolo.service.*Service.*(..))")public void servicePt() {}@Around("servicePt()")public void runSpeed(ProceedingJoinPoint point) throws Throwable {long start = System.currentTimeMillis();for (int i = 0; i < 10000; i++) {point.proceed();}long end = System.currentTimeMillis();System.out.println("业务层接口万次执行时间:" + (end - start) + "ms");}
}
  • 步骤五:运行单元测试类
    运行结果如下
    在这里插入图片描述
    在这里插入图片描述

  • 步骤六: 程序优化
    目前还存在一个问题,当我们一次执行多个方法时,控制台输出的都是业务层接口万次执行时间: XXXms
    我们无法得知具体哪个方法的耗时,那么该如何优化呢?
    ProceedingJoinPoint中有一个getSignature()方法来获取签名,然后调用getDeclaringTypeName可以获取类名,getName()可以获取方法名

@Component
@Aspect
public class ProjectAdvice {@Pointcut("execution(* com.yolo.service.*Service.*(..))")public void servicePt() {}@Around("servicePt()")public void runSpeed(ProceedingJoinPoint point) throws Throwable {//Signature指签名信息,可理解为封装了这次执行过程Signature signature = point.getSignature();//获取类名String className = String.valueOf(signature.getDeclaringType());//获取方法名String methodName = signature.getName();long start = System.currentTimeMillis();for (int i = 0; i < 10000; i++) {point.proceed();}long end = System.currentTimeMillis();System.out.println("业务层接口万次执行时间:" + className + "." +methodName + "耗时" + (end - start) + "ms");}
}

再次运行程序,结果如下
在这里插入图片描述

版权声明:

本网仅为发布的内容提供存储空间,不对发表、转载的内容提供任何形式的保证。凡本网注明“来源:XXX网络”的作品,均转载自其它媒体,著作权归作者所有,商业转载请联系作者获得授权,非商业转载请注明出处。

我们尊重并感谢每一位作者,均已注明文章来源和作者。如因作品内容、版权或其它问题,请及时与我们联系,联系邮箱:809451989@qq.com,投稿邮箱:809451989@qq.com