Ja 企业应用基础及开发- 2_第1页
Ja 企业应用基础及开发- 2_第2页
Ja 企业应用基础及开发- 2_第3页
Ja 企业应用基础及开发- 2_第4页
Ja 企业应用基础及开发- 2_第5页
已阅读5页,还剩50页未读 继续免费阅读

下载本文档

版权说明:本文档由用户提供并上传,收益归属内容提供方,若内容存在侵权,请进行举报或认领

文档简介

4.1认识Spring框架认识Spring框架Spring框架:企业级应用的标准化积木连接器想象搭建复杂乐高模型(类比企业级应用),Spring如同标准化积木连接器,让不同模块(组件)高效组合,减少重复造轮子。学习目标掌握核心思想、环境搭建及首个程序实现,为企业级开发奠定基础。学习目标与实践任务知识目标理解三大核心价值:解耦(IoC容器)、切面编程(AOP)、生态整合能力目标独立完成Spring6.x环境搭建编写“HelloSpring”程序对比传统开发与Spring开发效率差异实践任务基于JDK17,使用IoC容器实现“HelloWorld”,重点观察对象创建方式变化。Spring的诞生与核心价值诞生背景2003年,RodJohnson为解决EJB“重量级”复杂性发布Spring框架。三大核心创新IoC容器:从“自己做饭”(new对象)到“外卖点餐”(容器注入),彻底解耦AOP编程:如“监控摄像头”自动处理日志/事务,业务代码专注核心逻辑生态整合:无缝对接MyBatis、SpringMVC、SpringBoot,形成JavaEE“瑞士军刀”数据对比:使用Spring后,重复代码减少40%,模块复用率提升60%(来源:Spring官方白皮书)核心概念——IoC容器(控制反转)代码对比传统开发(硬编码依赖):UserService.javapublicclassOrderService{privateUserDaodao=newUserDaoImpl();//依赖绑定死实现类}Spring开发(容器注入):UserService.java@ServicepublicclassOrderService{@Autowired//容器自动匹配UserDao实现类privateUserDaodao;}类比理解:传统方式“自己种咖啡豆”(new),IoC让“星巴克(容器)送咖啡”(注入),专注“喝咖啡”(业务逻辑)IoC容器工作流程图Bean定义(XML/注解)实例化(创建Bean对象)依赖注入(DI)[数据来源:]核心概念——AOP编程(面向切面)AOP切面示意图目标方法(TargetMethod)前置通知@Before环绕通知@Around后置返回@AfterReturning异常通知@AfterThrowing最终通知@After切面(Aspect)[数据来源:博客园-AOP五种通知类型]代码对比传统方式(侵入业务代码):publicvoidaddOrder(){("开始添加订单");//重复代码//业务逻辑...("结束添加订单");//重复代码}AOP方式(无侵入):@Aspect@ComponentpublicclassLogAspect{@Before("execution(*com.example.service.*.*(..))")publicvoidlogBefore(){System.out.println("方法执行前记录日志");}}效果:10个Service类×5个方法=50处日志代码,现在只需1个切面类搞定!Spring6.x新特性与环境准备三大突破Java17基线:强制JDK17+,支持密封类、模式匹配虚拟线程(ProjectLoom):轻量级线程处理10万级并发,性能提升300%GraalVM原生镜像:启动时间从秒级→毫秒级,内存占用减少70%环境搭建步骤安装JDK17(推荐AmazonCorretto)配置Maven依赖:spring-context:6.1.0安装IntelliJIDEA2023+(支持SpringBoot插件)分步实现——创建Maven项目创建步骤项目结构关键依赖配置<dependency><groupId>org.springframework</groupId><artifactId>spring-context</artifactId><version>6.1.0</version></dependency>选择MavenArchetype→maven-archetype-quickstart✓GroupId:com.example,ArtifactId:hello-spring✓等待Maven自动下载依赖✓-src/main/java:源码目录✓-pom.xml:依赖配置文件✓分步实现——编写Service类HelloService类代码packagecom.example.service;importorg.springframework.stereotype.Service;@Service//标记为Spring管理的服务类public

class

HelloService{publicStringsayHello(){return"HelloSpring6.x!";//核⼼业务逻辑}}原理说明@Service注解等效于XML配置:<beanid="helloService"class="com.example.service.HelloService"/>Spring容器自动扫描:带@Service的类会被自动发现并注册为Spring容器中的“可复用组件”。分步实现——编写配置类AppConfig配置类代码packagecom.example.config;importorg.springframework.context.annotation.ComponentScan;importorg.springframework.context.annotation.Configuration;@Configuration//标记为配置类@ComponentScan("com.example.service")//扫描指定包下的BeanpublicclassAppConfig{}类比理解相当于告诉Spring:“去com.example.service文件夹找所有贴了@Service的类,我要用它们!”注意事项漏写@ComponentScan会导致Spring“找不到”HelloService,从而引发依赖注入失败。分步实现——编写启动类App启动类代码package

com.example;import

com.example.config.AppConfig;import

com.example.service.HelloService;import

org.springframework.context.annotation.AnnotationConfigApplicationContext;public

class

App{publicstaticvoidmain(String[]args){

//初始化Spring容器varcontext=newAnnotationConfigApplicationContext(AppConfig.class);

//获取HelloServiceBeanHelloServicehelloService=context.getBean(HelloService.class);

//调用方法输出结果System.out.println(helloService.sayHello());//打印"HelloSpring6.x!"

context.close();//关闭容器}}执行流程容器初始化→扫描Bean→注入依赖→调用方法,全程无需手动new对象!核心思想控制反转(IoC)是Spring的核心。通过将对象的创建和依赖管理交给Spring容器,我们可以专注于业务逻辑的实现,极大地降低了组件间的耦合度。运行效果图与关键说明运行成功输出控制台打印:HelloSpring6.x!关键问题解答为什么不用newHelloService()?→@Service和@ComponentScan让Spring自动创建对象,存于“容器仓库”,需用时直接取用。@Autowired注入失败怎么办?→检查:①类是否加@Service②包路径是否被@ComponentScan扫描③是否存在循环引用(A依赖B,B依赖A)对比传统开发与Spring开发传统开发与Spring开发对比表维度传统开发Spring开发对象创建HelloServiceservice=newHelloService()@AutowiredHelloServiceservice依赖管理硬编码绑定实现类容器动态匹配依赖修改成本改代码→重新编译→部署修改配置→热加载生效测试难度需要手动模拟依赖对象容器可直接注入Mock对象结论:Spring如同“智能管家”,打理对象“生老病死”,让你专注业务创新!Spring6.x新特性实战虚拟线程特性代码对比传统线程池(200线程上限):ExecutorServiceexecutor=Executors.newFixedThreadPool(200);虚拟线程(10万级并发):ExecutorServiceexecutor=Executors.newVirtualThreadPerTaskExecutor();//处理10000个请求仅需5MB内存IntStream.range(0,10000).forEach(i->executor.submit(()->processOrder(i)));性能提升数据:启动时间从4.5秒→0.8秒,内存占用从1.2GB→150MB(GraalVM原生镜像编译)[数据来源:]常见问题与解决方案Q1:@Autowired报NullPointerException?A:检查①类是否加@Service②包路径是否被@ComponentScan扫描(如服务类在com.example.service,配置类却扫描com.example.dao)Q2:JDK版本不兼容?A:Spring6.x要求JDK≥17,需在IDEA中配置ProjectSDK为17+,并在pom.xml指定:<piler.source>17</piler.source>Q3:虚拟线程不生效?A:需使用JDK19+,并添加启动参数:--enable-preview总结与进阶学习核心知识点两大支柱:IoC容器(对象管理)+AOP(横切逻辑)开发四步:加依赖→写Bean→配扫描→调容器关键注解:@Service(标记Bean)、@Autowired(注入依赖)、@Configuration(配置类)进阶路线底层原理:IoC容器Bean生命周期、AOP动态代理(JDK/CGLIB)实战技能:SpringBoot自动配置、SpringCloud微服务性能优化:缓存机制(一级/二级缓存)、异步编程(@Async)下节课预告:解剖IoC容器的“五脏六腑”,揭开Spring“黑盒”面纱!4.2SpringIoCSpringIoC深度解析:核心原理与企业级实践SpringIoC:Java开发的“神经中枢”同学们好!今天我们深入探讨Spring框架的核心——IoC容器。如果说Spring是Java开发的“大脑”,那么IoC就是“神经中枢”,负责对象的创建、依赖管理和生命周期控制。通过本节15页PPT的学习,你将掌握IoC的设计思想、依赖注入实现方式及企业级应用技巧,为后续框架整合打下基础。学习目标与议程知识目标理解IoC/DI的核心原理掌握3种依赖注入方式(构造器/Setter/字段)区分Bean的4种作用域(单例/原型/请求/会话)能力目标使用注解配置IoC容器(@Component、@Autowired)分析IoC容器初始化流程解决循环依赖等常见问题议程概念→原理→实践→案例→拓展逐步揭开IoC的神秘面纱!IoC/DI概念——控制反转与依赖注入传统开发痛点publicclassOrderService{privateUserDaouserDao=newUserDaoImpl();//硬编码依赖privateLogServicelogService=newLogService();}→修改依赖需改代码,耦合度高!IoC解决方案控制反转(IoC):对象创建从“手动new”→“容器自动生成”依赖注入(DI):容器通过构造器/Setter将依赖对象“注入”目标类类比:IoC容器=‘对象工厂+外卖小哥’,你(目标类)只需下单(声明依赖),工厂生产对象,小哥送货上门(注入)!IoC容器初始化流程——四步构建IoC容器启动四步曲资源定位:读取配置类(@Configuration)或XML,定位Bean定义BeanDefinition加载:解析配置为BeanDefinition(包含类名、属性、作用域等元数据)Bean注册:将BeanDefinition存入HashMap(beanDefinitionMap)实例化:非懒加载单例Bean在容器启动时创建,通过反射调用构造器代码追踪//容器初始化⼊⼝ApplicationContextcontext=newAnnotationConfigApplicationContext(AppConfig.class);//核心方法:AbstractApplicationContext#refresh()IoC容器初始化流程图1.资源定位2.BeanDefinition加载3.Bean注册4.实例化[数据来源:]依赖注入(DI)实战——构造器注入Spring6.x推荐方式构造器注入(强制依赖,不可变)@ServicepublicclassOrderService{privatefinalUserDaouserDao;privatefinalLogServicelogService;//构造器注⼊(Spring6.x可省略@Autowired)publicOrderService(UserDaouserDao,LogServicelogService){this.userDao=userDao;this.logService=logService;}}优势避免NPE(final字段必须初始化)便于单元测试(直接传入Mock对象)符合依赖不可变原则依赖注入(DI)实战——Setter注入适用场景可选依赖:当某个依赖项允许为null时,适合使用Setter注入。代码示例@Servicepublic

class

UserService

{privateUserDaouserDao;privateCacheServicecacheService;//Setter注入(需@Autowired)@Autowired(required=false)//非必须依赖publicvoidsetUserDao(UserDaouserDao){this.userDao=userDao;

}@AutowiredpublicvoidsetCacheService(CacheServicecacheService){this.cacheService=cacheService;

}}注意事项required=false表示依赖是可选的,允许为null。Setter方法名需遵循setXxx规范,以确保Spring能够正确识别。Setter注入的优先级低于构造器注入。灵活性与解耦Setter注入提供了在对象创建后动态更改依赖的能力,更适合处理可选依赖,从而增强代码的灵活性。依赖注入(DI)实战——字段注入简洁但不推荐直接在字段上使用@Autowired注解,代码量最少,非常直观。@ServicepublicclassProductService{@Autowired//字段注入(无构造器/Setter)privateProductDaoproductDao;@AutowiredprivateInventoryServiceinventoryService;}缺点无法注入final字段,限制了不可变对象的创建。单元测试时,需通过反射机制注入Mock对象,增加了测试复杂度。隐藏了类的依赖关系,通过构造器一目了然,而字段注入则需要查看类内部才能知晓。最佳实践:仅用于简单Demo或快速原型验证。企业级开发中,应优先使用构造器注入!Bean作用域——5种生命周期策略Bean作用域生命周期对比[数据来源:项目四Spring核心]Spring定义5种Bean作用域,默认单例(singleton):作用域生命周期应用场景singleton容器启动→销毁无状态服务(如工具类)prototype每次getBean()创建新实例有状态Bean(如Request对象)request一次HTTP请求内单例Web层请求共享数据session会话周期内单例用户会话数据(如购物车)代码配置示例:@Scope("prototype")//原型作⽤域@ComponentpublicclassCartService{}Bean生命周期——从创建到销毁单例Bean完整生命周期实例化:调用构造器创建对象属性填充:依赖注入(@Autowired)初始化:实现InitializingBean#afterPropertiesSet()自定义init-method(@Bean(initMethod="init"))@PostConstruct注解方法使用:容器中获取Bean销毁:实现DisposableBean#destroy()自定义destroy-method@PreDestroy注解方法代码示例@ComponentpublicclassOrderServiceimplementsInitializingBean,DisposableBean{

@PostConstructpublicvoidinit(){System.out.println("初始化");}

@PreDestroypublicvoiddestroy(){System.out.println("销毁");}

@OverridepublicvoidafterPropertiesSet()throwsException{//InitializingBean接口实现}

@Overridepublicvoiddestroy()throwsException{//DisposableBean接口实现}}注解驱动IoC——@ComponentScan自动扫描Bean@ComponentScan注解用于指定SpringIoC容器扫描组件的基础包路径。通过@ComponentScan指定扫描路径:@Configuration@ComponentScan(basePackages="com.example.service")//扫描包及子包public

class

AppConfig{

//被@Component、@Service、@Repository、@Controller标注的类将被⾃动注册为Bean}过滤规则可以通过includeFilters和excludeFilters示例://包含指定注解的Bean@ComponentScan(includeFilters=@Filte//排除指定类@ComponentScan(excludeFilters=@Filte@Autowired工作原理——依赖查找与注入@Autowired流程:查找→匹配→注入查找候选Bean:根据类型(byType)在容器中查找匹配Bean。匹配策略:-唯一匹配:直接注入。-多个匹配:结合@Qualifier指定Bean名称(byName)。-无匹配:@Autowired(required=false)则注入null,否则抛异常。注入:通过反射设置字段值或调用Setter方法。代码示例@ServicepublicclassUserService{@Autowired@Qualifier("userDaoImpl")//多实现时指定Bean名privateUserDaouserDao;

//...业务⽅法}@Resource与@Autowired对比特性@Autowired@Resource来源Spring注解JSR-250规范注解匹配方式先byType,后byName(需@Qualifier)先byName,后byType作用位置字段、构造器、Setter字段、Setter(不支持构造器)required属性支持(默认true)不支持(依赖必须存在)最佳实践Spring项目:@Autowired+@Qualifier跨框架兼容:@Resource(如JFinal、Micronaut)[数据来源:]循环依赖解决方案——三级缓存三级缓存解决循环依赖流程图A实例化→三级缓存B实例化→三级缓存B依赖A→二级缓存B完成→一级缓存A依赖B→一级缓存A完成→一级缓存[数据来源:CSDN博客]问题场景A依赖B,B依赖A,形成闭环。@ComponentpublicclassAService{@AutowiredprivateBServiceb;}@ComponentpublicclassBService{@AutowiredprivateAServicea;}Spring解决方案:三级缓存机制一级缓存:singletonObjects(存放完整、可用的Bean)二级缓存:earlySingletonObjects(存放提前暴露的半成品Bean,已实例化但未初始化)三级缓存:singletonFactories(存放Bean工厂,用于生成代理对象,解决代理Bean的循环依赖)核心逻辑:通过提前暴露未初始化的Bean引用(放入二级或三级缓存),使得依赖它的Bean可以先完成初始化,从而打破循环依赖。企业级案例——IoC容器整合MyBatisSpringIoC整合MyBatis关键步骤配置数据源:DruidDataSource注入到SqlSessionFactorySqlSessionFactoryBean:IoC容器管理MyBatis会话工厂Mapper接口扫描:@MapperScan自动注册Mapper代理Bean核心配置@Configuration@MapperScan("com.example.mapper")//扫描Mapper接口public

class

MyBatisConfig{@BeanpublicSqlSessionFactorysqlSessionFactory(DataSourcedataSource)throwsException{SqlSessionFactoryBeanbean=newSqlSessionFactoryBean();bean.setDataSource(dataSource);returnbean.getObject();}}总结与面试重点核心考点IoC/DI本质:控制反转+依赖注入,解耦组件依赖注入方式:构造器注入(推荐)、Setter注入、字段注入Bean作用域:单例vs原型,Web作用域(request/session)循环依赖:三级缓存(singletonFactories→earlySingletonObjects→singletonObjects)注解驱动:@ComponentScan、@Autowired、@Bean实践建议企业开发:优先构造器注入+注解配置性能优化:原型Bean谨慎使用,避免频繁创建对象源码学习:重点阅读AbstractApplicationContext#refresh()预告:下节课学习SpringAOP,揭秘事务管理底层实现!4.3SpringAOP01教师出镜面向切面编程(AOP)01教师出镜用户查询功能日志记录权限检查事务管理√√√附加功能核心业务AOP完美分离一、AOP概念导入传统开发的痛点假设我们有10个Service类,每个类的增删改查方法都需要记录日志。传统做法就是在每个方法里写(...)——10个类×4个方法=40处重复代码!以后要改日志格式,得改40个地方,简直是灾难!一、AOP概念导入AOP的解决方案AOP把这些横切关注点(比如日志、事务)从业务逻辑中"剥离"出来,做成独立的"切面",然后"织入"到目标方法中。(文字不用在视频中呈现,配相对应的素材)就像给蛋糕裱花——蛋糕(核心业务)做好后,用裱花袋(切面)把奶油(横切功能)挤上去,既美观又不影响蛋糕本身的味道!二、AOP核心概念核心术语切面(Aspect):封装横切关注点的模块(如日志切面)概念关系图切面(Aspect)通知(Advice)切点(Pointcut)连接点(JoinPoint)织入(Weaving)——就是那个"裱花袋"(配图,文字不用在视频中呈现)二、AOP核心概念核心术语连接点(JoinPoint):程序执行的特定点(如方法调用)概念关系图切面(Aspect)通知(Advice)切点(Pointcut)连接点(JoinPoint)织入(Weaving)——可以裱花的位置(配图,文字不用在视频中呈现)二、AOP核心概念核心术语通知(Advice):切面在连接点执行的操作(前置/后置/环绕通知等)概念关系图切面(Aspect)通知(Advice)切点(Pointcut)连接点(JoinPoint)织入(Weaving)——就是"挤奶油"的动作(配图,文字不用在视频中呈现)二、AOP核心概念核心术语切点(Pointcut):匹配连接点的表达式概念关系图切面(Aspect)通知(Advice)切点(Pointcut)连接点(JoinPoint)织入(Weaving)——就是"在哪里裱花"(配图,文字不用在视频中呈现)二、AOP核心概念核心术语织入(Weaving):将切面应用到目标对象的过程概念关系图切面(Aspect)通知(Advice)切点(Pointcut)连接点(JoinPoint)织入(Weaving)——就是那个"裱花袋"(配图,文字不用在视频中呈现)重点:切点表达式是AOP的"导航系统",能精确命中你想要增强的方法!三、AOP与OOP对比

OOP(面向对象)

AOP(面向切面)关注业务实体的封装——处理"名词领域",比如User类、OrderService接口关注业务过程中的步骤——处理"动词领域",比如记录日志、检查权限三、AOP与OOP对比OOPUser类(数据)和UserService.getUser()方法(操作)AOP在getUser()执行前后自动记录日志不是竞争关系,而是"黄金搭档"搭骨架填血肉四、SpringAOP环境准备05核心依赖1核心依赖配置(pom.xml)核心依赖2核心依赖配置(pom.xml)重点:两个依赖缺一不可。提供IoC容器,管理Bean的创建和依赖AOP的"手术刀",负责把切面"切"进目标方法(专业叫"织入")记住:少了aspectjweaver,AOP注解(@Aspect、@Before等)会无效,控制台可能报"无法找到AspectJ类"的错误!//xml<!--Spring上下文依赖--><dependency>

<groupId>org.springframework</groupId>

<artifactId>spring-context</artifactId>

<version>6.1.0</version></dependency><!--AspectJ织入器依赖--><dependency>

<groupId>org.aspectj</groupId>

<artifactId>aspectjweaver</artifactId>

<version>1.9.7</version></dependency>06五、目标业务类设计

(实体与接口)User.java(实体类)://javapublicclassUser{

privateStringuserNo;//用户编号

privateStringuserName;//用户姓名

//构造方法、getter/setter、toString()}UserService接口://javapublicinterfaceUserService{

UsergetUser(StringuserId);//查询用户}06五、目标业务类设计这个业务类很干净,没有任何日志、事务相关的代码。代码与文稿对应不上,需核对AOP追求的"纯粹"UserServiceImpl实现类://javapublicclassUserServiceImplimplementsUserService{

@Override

publicUsergetUser(StringuserId){

returnnewUser(userId,"张三");//模拟查询数据库

}}六、切面类实现(LoggingAspect.java)07前置通知(BeforeAdvice)**日志切面类代码**:@Aspect//声明为切面类@Component//交由Spring容器管理publicclassLoggingAspect{@Before("execution(*UserService.getUser(..))")publicvoidbeforeAdvice(JoinPointjoinPoint){System.out.println("前置通知:开始执行"+joinPoint.getSignature().getName()+"⽅法");}}后置通知(AfterAdv**日志切面类代码**:@After("execution(*UspublicvoidafterAdvicSystem.out.println("}}重点切点表达式execution(*Use代码与文稿对应不上,需核对七、Spring配置文件(applicationContext.xml)08

(Bean定义)<beanid="userService"class="UserServiceImpl"/><beanid="loggingAspect"class="LoggingAspect"/>定义目标Bean和切面Bean。

(AOP配置)<aop:config><aop:aspectref="loggingAspect"><aop:pointcutid="userServicePo

温馨提示

  • 1. 本站所有资源如无特殊说明,都需要本地电脑安装OFFICE2007和PDF阅读器。图纸软件为CAD,CAXA,PROE,UG,SolidWorks等.压缩文件请下载最新的WinRAR软件解压。
  • 2. 本站的文档不包含任何第三方提供的附件图纸等,如果需要附件,请联系上传者。文件的所有权益归上传用户所有。
  • 3. 本站RAR压缩包中若带图纸,网页内容里面会有图纸预览,若没有图纸预览就没有图纸。
  • 4. 未经权益所有人同意不得将文件中的内容挪作商业或盈利用途。
  • 5. 人人文库网仅提供信息存储空间,仅对用户上传内容的表现方式做保护处理,对用户上传分享的文档内容本身不做任何修改或编辑,并不能对任何下载内容负责。
  • 6. 下载文件中如有侵权或不适当内容,请与我们联系,我们立即纠正。
  • 7. 本站不保证下载资源的准确性、安全性和完整性, 同时也不承担用户因使用这些下载资源对自己和他人造成任何形式的伤害或损失。

评论

0/150

提交评论