专栏电商日志财经减肥爱情
投稿投诉
爱情常识
搭配分娩
减肥两性
孕期塑形
财经教案
论文美文
日志体育
养生学堂
电商科学
头戴业界
专栏星座
用品音乐

一篇文章带你掌握主流基础框架Spring

  这篇文章中我们将会介绍Spring的框架以及本体内容,包括核心容器,注解开发,AOP以及事务等内容
  那么简单说明一下Spring的必要性:Spring技术是JavaEE开发的必备技能,企业开发技术选型率高达90!Spring可以帮助简化开发,降低企业级开发的复杂度Spring可以进行框架整合,高效整合其他技术,提高企业级应用开发与运行效率
  Spring的核心内容:Ioc技术DI技术AOP事务处理
  Spring可进行的框架整合:MaBatisMyBatisplusStrutsStruts2Hibernate
  在接下来的文章中,我们会学习Spring的框架思想,学习Spring的基本操作,结合案例熟练掌握温馨提醒:在学习本篇文章前请先学习JavaWeb相关内容
  (HTTP,Tomcat,Servlet,Request,Response,MVC,Cookie,Session,Ajax,Vue等内容)初识Spring
  官网:SpringHome
  Spring发展至今已经形成了一套开发的生态圈,Spring提供了相当多的项目,每个项目用于完成特定功能
  我们常用的主流技术包括有:SpringFramework:Spring框架SpringBoot:Spring简化代码开发SpringCloud:Spring分布设计SpringFrameWork系统架构
  在系统学习Spring之前,我们需要先来了解FrameWork系统结构SpringFrameWork是Spring生态圈中最基本的项目,是其他项目的根基
  我们现在所使用的SpringFrameWork是4。0版本,已经趋于稳定
  下面我们对架构图进行解释:CoreContainer:核心容器AOP:面向切面编程Aspects:AOP思想实现DataAccess:数据访问DataIntergration:数据集成Web:Web开发Test:单元测试与集成测试
  我们可以在官方中获得如此评价:强大的基于JavaBeans的采用控制反转(InversionofControl,IoC)原则的配置管理,使得应用程序的组建更加快捷简易。数据库事务的一般化抽象层,允许插件式事务管理器,简化事务的划分使之与底层无关。一个可用于从applet到JavaEE等不同运行环境的核心Bean工厂。核心概念介绍
  首先我们思索一下我们之前的业务层与数据层:数据层接口publicinterfaceBookDao{publicvoidsave();}数据层实现publicclassBookDaoImplimplementsBookDao{publicvoidsave(){System。out。println(bookdaosave。。。);}}业务层接口publicinterfaceBookService{publicvoidsave();}业务层实现publicclassBookServiceImplimplementsBookService{privateBookDaobookDao;publicvoidsave(){bookDao。save();}}
  如果我们修改BookDaoImpl内容,那么相对应的业务层实现中的bookDao的new实现也要进行修改,甚至下方方法的对象也要进行修改Spring使用前问题
  代码书写现状:耦合度偏高
  解放方案:使用对象时,在程序中不要主动使用new产生对象,转换为由外部提供对象Spring思想以及实现
  IoC(InversionofControl)控制反转思想:使用对象时,由主动new创建对象转换为由外部提供对象此过程中对象创建控制权由程序转移到外部,被称为控制反转
  DI(DependencyInjection)依赖注入:在容器中建立Bean与Bean之间的依赖关系和整个过程,被称为依赖注入
  Spring技术对Ioc思想进行了实现:Spring提供了一个容器,被称为Ioc容器,用来充当IoC思想的外部IoC容器负责对象的创建,初始化等一系列工作,被创建和管理的对象在IoC容器中被称为Bean数据层实现publicclassBookDaoImplimplementsBookDao{publicvoidsave(){System。out。println(bookdaosave。。。);}}IoC容器包含daoservice两者可以建立连接业务层实现publicclassBookServiceImplimplementsBookService{privateBookDaobookDao;publicvoidsave(){bookDao。save();}}
  目的:充分解耦IoC:使用IoC容器管理beanDI:在IoC容器内将有依赖关系的bean进行关系绑定
  最终效果:使用对象不仅可以直接从IoC容器中获取,还可以将已获得的Bean之间绑定依赖关系IoC入门
  首先我们需要明白IoC的使用规则:IoC负责管理什么:Service和Dao如何被管理的对象告知IoC容器:(配置)被管理的对象交给IoC容器,如何获得IoC容器:(接口)IoC容器得到之后,如何获得Bean:(接口方法)使用Spring所需要导入的坐标:(pom。xml)
  下面我们给出IoC入门的详细步骤:创建Maven项目,在pom。xml中导入坐标dependenciesdependencygroupIdorg。springframeworkgroupIdspringcontextartifactIdversion5。2。10。RELEASEversiondependencydependencies创建Spring。xml的配置包(applicationContext。xml,导入坐标后xml中更新该XML)lt;?xmlversion1。0encodingUTF8?beansxmlnshttp:www。springframework。orgschemabeansxmlns:xsihttp:www。w3。org2001XMLSchemainstancexsi:schemaLocationhttp:www。springframework。orgschemabeanshttp:www。springframework。orgschemabeansspringbeans。xsd!2。配置bean!bean标签标示配置beanid属性标示给bean起名字class属性表示给bean定义类型(注意需要是实现类)beanidbookDaoclasscom。itheima。dao。impl。BookDaoImplbeanidbookServiceclasscom。itheima。service。impl。BookServiceImplbeans主函数packagecom。itheima;importcom。itheima。dao。BookDao;importcom。itheima。service。BookService;importorg。springframework。context。ApplicationContext;importorg。springframework。context。support。ClassPathXmlApplicationContext;publicclassApp2{publicstaticvoidmain(String〔〕args){3。获取IoC容器ApplicationContextctxnewClassPathXmlApplicationContext(applicationContext。xml);4。获取bean(根据bean配置id获取)BookDaobookDao(BookDao)ctx。getBean(bookDao);bookDao。save();注意:需要类型转化BookServicebookService(BookService)ctx。getBean(bookService);bookService。save();}}DI入门
  首先我们需要明白DI的使用规则:基于IoC管理beanService中使用new形式创建Dao对象是否保留:(否)Service中需要Dao对象如何进入到Service中:(提供方法)Service与Dao之间的关系如何描述:(配置)
  下面我们给出DI入门的详细步骤(基于IoC入门):删除new方法publicclassBookServiceImplimplementsBookService{5。删除业务层中使用new的方式创建的dao对象privateBookDaobookDao;publicvoidsave(){System。out。println(bookservicesave。。。);bookDao。save();}}创建对象的set方法publicclassBookServiceImplimplementsBookService{5。删除业务层中使用new的方式创建的dao对象privateBookDaobookDao;publicvoidsave(){System。out。println(bookservicesave。。。);bookDao。save();}6。提供对应的set方法publicvoidsetBookDao(BookDaobookDao){this。bookDaobookDao;}}创建Dao和Service的连接lt;?xmlversion1。0encodingUTF8?beansxmlnshttp:www。springframework。orgschemabeansxmlns:xsihttp:www。w3。org2001XMLSchemainstancexsi:schemaLocationhttp:www。springframework。orgschemabeanshttp:www。springframework。orgschemabeansspringbeans。xsd!2。配置bean!bean标签标示配置beanid属性标示给bean起名字class属性表示给bean定义类型beanidbookDaoclasscom。itheima。dao。impl。BookDaoImplbeanidbookServiceclasscom。itheima。service。impl。BookServiceImpl!7。配置server与dao的关系!注意:在server中配置关系property标签表示配置当前bean的属性name属性表示配置哪一个具体的属性ref属性表示参照哪一个beanpropertynamebookDaorefbookDaobeanbeansBean整体介绍
  Bean是保存在IoC中的对象,我们通过配置的方式获得Bean
  下面我们从三个方面分别讲解Bean:bean基本配置
  首先我们先介绍bean本身性质:
  类别
  描述
  名称
  bean
  类型
  标签
  所属
  beans标签
  功能
  定义Spring核心容器管理对象
  格式
  属性列表
  id:bean的id,使用容器可以通过id值获得对应的bean,在一个容器中id值唯一
  class:bean的类型,即配置的bean的全路径类名
  范例
  然后我们介绍一下bean的别名:
  类别
  描述
  名称
  name
  类型
  标签
  所属
  bean标签
  功能
  定义bean的别名,可定义多个,使用逗号,分号,空格分隔
  范例
  正常情况下,使用id和name都可以获得bean,但推荐还是使用唯一id
  获得bean无论通过id还是name获取,如果无法找到则抛出异常NosuchBeanDefinitionException
  最后我们介绍一下bean的作用范围scope:
  类别
  描述
  名称
  scope
  类型
  标签
  所属
  bean标签
  功能
  定义bean的作用范围,可选范围如下:
  singleton:单列(默认)
  prototype:非单列
  范例
  这里的scope指产生对象的数量
  我们的scope在默认情况下是singleton,因为很多对象只需要创建一次,多次创建会导致内存膨胀
  合适交给容器进行管理的bean(singleton):
  表现层对象业务层对象数据层对象工具对象
  不合适交给容器进行管理的bean(prototype):
  封装实体的域对象(带有状态的bean)bean实例化
  bean的实例化通常分为四种方法,我们在下面一一介绍:构造方法(常用)
  我们需要在数据类中提供构造方法,配置条件中不需要改变数据类publicclassBookDaoImplimplementsBookDao{publicBookDaoImpl(){System。out。println(bookdaoconstructorisrunning。。。。);}publicvoidsave(){System。out。println(bookdaosave。。。);}}lt;?xmlversion1。0encodingUTF8?beansxmlnshttp:www。springframework。orgschemabeansxmlns:xsihttp:www。w3。org2001XMLSchemainstancexsi:schemaLocationhttp:www。springframework。orgschemabeanshttp:www。springframework。orgschemabeansspringbeans。xsd!方式一:构造方法实例化beanbeanidbookDaoclasscom。itheima。dao。impl。BookDaoImplbeans
  若无参构造方法不存在,则抛出异常BeanCreationException静态工厂(了解)
  我们在之前的案例中存在有对象工厂的说法,我们可以设置工厂并调用其方法得到bean静态工厂packagecom。itheima。factory;importcom。itheima。dao。OrderDao;importcom。itheima。dao。impl。OrderDaoImpl;静态工厂创建对象publicclassOrderDaoFactory{publicstaticOrderDaogetOrderDao(){System。out。println(factorysetup。。。。);returnnewOrderDaoImpl();}}lt;?xmlversion1。0encodingUTF8?beansxmlnshttp:www。springframework。orgschemabeansxmlns:xsihttp:www。w3。org2001XMLSchemainstancexsi:schemaLocationhttp:www。springframework。orgschemabeanshttp:www。springframework。orgschemabeansspringbeans。xsd!方式二:使用静态工厂实例化beanbeanidorderDaoclasscom。itheima。factory。OrderDaoFactoryfactorymethodgetOrderDaobeans实例工厂(了解)
  和静态工厂相同,但不同点是方法不是静态,我们需要提前创建一个bean实例工厂packagecom。itheima。factory;importcom。itheima。dao。UserDao;importcom。itheima。dao。impl。UserDaoImpl;实例工厂创建对象publicclassUserDaoFactory{publicUserDaogetUserDao(){returnnewUserDaoImpl();}}lt;?xmlversion1。0encodingUTF8?beansxmlnshttp:www。springframework。orgschemabeansxmlns:xsihttp:www。w3。org2001XMLSchemainstancexsi:schemaLocationhttp:www。springframework。orgschemabeanshttp:www。springframework。orgschemabeansspringbeans。xsd!方式三:使用实例工厂实例化beanbeaniduserFactoryclasscom。itheima。factory。UserDaoFactory!factorybean:实例工厂本身beanfactorymethod:使用调用bean的方法beaniduserDaofactorymethodgetUserDaofactorybeanuserFactorybeansFactoryBean(重要实用)
  除了我们之前自己定义的工厂外,Spring提供了一种官方版本的FactoryBeanFactoryBean工厂(需接口,中填写数据类接口)packagecom。itheima。factory;importcom。itheima。dao。UserDao;importcom。itheima。dao。impl。UserDaoImpl;importorg。springframework。beans。factory。FactoryBean;FactoryBean创建对象publicclassUserDaoFactoryBeanimplementsFactoryBeanUserDao{代替原始实例工厂中创建对象的方法返回创建对象类型为UserDaoImpl()publicUserDaogetObject()throwsException{returnnewUserDaoImpl();}这里填写接口类型publicClasslt;?getObjectType(){returnUserDao。class;}可以修改来修改其scope属性publicbooleanisSingleton(){returnfalse;}}lt;?xmlversion1。0encodingUTF8?beansxmlnshttp:www。springframework。orgschemabeansxmlns:xsihttp:www。w3。org2001XMLSchemainstancexsi:schemaLocationhttp:www。springframework。orgschemabeanshttp:www。springframework。orgschemabeansspringbeans。xsd!方式四:使用FactoryBean实例化beanbeaniduserDaoclasscom。itheima。factory。UserDaoFactoryBeanbeansbean生命周期
  我们先来接单介绍生命周期相关概念:生命周期:从创建到消亡的完整过程bean生命周期:bean从创建到销毁的整体过程bean生命周期控制:在bean创建后到销毁前做一些事情
  接下来我们介绍生命周期控制方法:数据层提供控制方法
  由数据层提供方法,在xml配置文件中设置该方法数据层packagecom。itheima。dao。impl;importcom。itheima。dao。BookDao;publicclassBookDaoImplimplementsBookDao{publicvoidsave(){System。out。println(bookdaosave。。。);}表示bean初始化对应的操作publicvoidinit(){System。out。println(init。。。);}表示bean销毁前对应的操作publicvoiddestory(){System。out。println(destory。。。);}}!配置文件lt;?xmlversion1。0encodingUTF8?beansxmlnshttp:www。springframework。orgschemabeansxmlns:xsihttp:www。w3。org2001XMLSchemainstancexsi:schemaLocationhttp:www。springframework。orgschemabeanshttp:www。springframework。orgschemabeansspringbeans。xsd!initmethod:设置bean初始化生命周期回调函数!destroymethod:设置bean销毁生命周期回调函数,仅适用于单例对象beanidbookDaoclasscom。itheima。dao。impl。BookDaoImplinitmethodinitdestroymethoddestorybeanidbookServiceclasscom。itheima。service。impl。BookServiceImplpropertynamebookDaorefbookDaobeanbeans接口控制方法(了解)
  Spring为创建提供了两个接口,我们只需要继承并实现该方法即可packagecom。itheima。service。impl;importcom。itheima。dao。BookDao;importcom。itheima。service。BookService;importorg。springframework。beans。factory。DisposableBean;importorg。springframework。beans。factory。InitializingBean;InitializingBean,DisposableBean分别对应afterPropertiesSet,destroy方法,代表创建和销毁publicclassBookServiceImplimplementsBookService,InitializingBean,DisposableBean{privateBookDaobookDao;publicvoidsetBookDao(BookDaobookDao){System。out。println(set。。。。。);this。bookDaobookDao;}publicvoidsave(){System。out。println(bookservicesave。。。);bookDao。save();}publicvoiddestroy()throwsException{System。out。println(servicedestroy);}publicvoidafterPropertiesSet()throwsException{System。out。println(serviceinit);}}lt;?xmlversion1。0encodingUTF8?beansxmlnshttp:www。springframework。orgschemabeansxmlns:xsihttp:www。w3。org2001XMLSchemainstancexsi:schemaLocationhttp:www。springframework。orgschemabeanshttp:www。springframework。orgschemabeansspringbeans。xsdbeanidbookDaoclasscom。itheima。dao。impl。BookDaoImplinitmethodinitdestroymethoddestory!直接调用即可beanidbookServiceclasscom。itheima。service。impl。BookServiceImplpropertynamebookDaorefbookDaobeanbeans
  我们需要提及一下bean的销毁时机:(了解即可)因为默认情况下,我们的bean不会被销毁,因为虚拟机会直接退出,ClassPathXmlApplicationContext会被忽略销毁过程
  所以如果我们希望销毁bean观察到destroy的实现,需要手动关闭:手动关闭容器方法:packagecom。itheima;importcom。itheima。dao。BookDao;importorg。springframework。context。ApplicationContext;importorg。springframework。context。support。ClassPathXmlApplicationContext;publicclassAppForLifeCycle{publicstaticvoidmain(String〔〕args){注意:这里需要采用ClassPathXmlApplicationContext作为对象,因为只有这个类才具有close方法ClassPathXmlApplicationContextctxnewClassPathXmlApplicationContext(applicationContext。xml);BookDaobookDao(BookDao)ctx。getBean(bookDao);bookDao。save();关闭容器ctx。close();}}注册关闭钩子,在虚拟机退出前先关闭容器再推出虚拟机packagecom。itheima;importcom。itheima。dao。BookDao;importorg。springframework。context。ApplicationContext;importorg。springframework。context。support。ClassPathXmlApplicationContext;publicclassAppForLifeCycle{publicstaticvoidmain(String〔〕args){ClassPathXmlApplicationContextctxnewClassPathXmlApplicationContext(applicationContext。xml);BookDaobookDao(BookDao)ctx。getBean(bookDao);bookDao。save();注册关闭钩子函数,在虚拟机退出之前回调此函数,关闭容器ctx。registerShutdownHook();}}最后我们统计一下整体生命周期:
  初始化容器:创建对象(分配内存)执行构造方法执行属性注入(set操作)执行bean初始化方法使用bean:执行业务操作关闭销毁容器:执行bean销毁方法依赖注入方式
  首先我们要知道类中传递数据的方法有两种:普通方法(Set方法)构造方法
  然后我们要知道数据的类型大体分为两种:引入类型(数据层)简单类型(基本数据类型和String)
  所以我们把依赖注入方式分为四种:setter注入简单类型引用类型构造器注入简单类型引入类型setter注入简单类型
  首先我们需要在bean种定义简单类型属性并提供可以访问的set方法packagecom。itheima。dao。impl;importcom。itheima。dao。BookDao;publicclassBookDaoImplimplementsBookDao{privateStringdatabaseName;privateintconnectionNum;setter注入需要提供要注入对象的set方法publicvoidsetConnectionNum(intconnectionNum){this。connectionNumconnectionNum;}setter注入需要提供要注入对象的set方法publicvoidsetDatabaseName(StringdatabaseName){this。databaseNamedatabaseName;}publicvoidsave(){System。out。println(bookdaosave。。。databaseName,connectionNum);}}
  然后在配置中使用property标签value属性注入简单类型数据lt;?xmlversion1。0encodingUTF8?beansxmlnshttp:www。springframework。orgschemabeansxmlns:xsihttp:www。w3。org2001XMLSchemainstancexsi:schemaLocationhttp:www。springframework。orgschemabeanshttp:www。springframework。orgschemabeansspringbeans。xsd!注入简单类型beanidbookDaoclasscom。itheima。dao。impl。BookDaoImpl!property标签:设置注入属性!name属性:设置注入的属性名,实际是set方法对应的名称!value属性:设置注入简单类型数据值propertynameconnectionNumvalue100propertynamedatabaseNamevaluemysqlbeanbeanssetter注入引用类型
  首先我们需要在bean种定义引用类型属性并提供可以访问的set方法packagecom。itheima。service。impl;importcom。itheima。dao。BookDao;importcom。itheima。dao。UserDao;importcom。itheima。service。BookService;publicclassBookServiceImplimplementsBookService{privateBookDaobookDao;privateUserDaouserDao;setter注入需要提供要注入对象的set方法publicvoidsetUserDao(UserDaouserDao){this。userDaouserDao;}setter注入需要提供要注入对象的set方法publicvoidsetBookDao(BookDaobookDao){this。bookDaobookDao;}publicvoidsave(){System。out。println(bookservicesave。。。);bookDao。save();userDao。save();}}
  然后在配置中使用property标签ref属性注入引用类型数据lt;?xmlversion1。0encodingUTF8?beansxmlnshttp:www。springframework。orgschemabeansxmlns:xsihttp:www。w3。org2001XMLSchemainstancexsi:schemaLocationhttp:www。springframework。orgschemabeanshttp:www。springframework。orgschemabeansspringbeans。xsdbeanidbookDaoclasscom。itheima。dao。impl。BookDaoImplpropertynameconnectionNumvalue100propertynamedatabaseNamevaluemysqlbeanbeaniduserDaoclasscom。itheima。dao。impl。UserDaoImpl!注入引用类型beanidbookServiceclasscom。itheima。service。impl。BookServiceImpl!property标签:设置注入属性!name属性:设置注入的属性名,实际是set方法对应的名称!ref属性:设置注入引用类型bean的id或namepropertynamebookDaorefbookDaopropertynameuserDaorefuserDaobeanbeans构造器注入简单类型(了解)
  在bean中定义简单类型属性并提供可访问的set方法publicclassBookDaoImplimplementsBookDao{privateintconnectionNumber;pubilcvoidsetConnectionNumber(intconnectionNumber){this。connectionNumberconnectionNumber;}}
  配置中使用constructorarg标签value属性注入简单类型数据lt;?xmlversion1。0encodingUTF8?beansxmlnshttp:www。springframework。orgschemabeansxmlns:xsihttp:www。w3。org2001XMLSchemainstancexsi:schemaLocationhttp:www。springframework。orgschemabeanshttp:www。springframework。orgschemabeansspringbeans。xsdbeanidbookDaoclasscom。itheima。dao。impl。BookDaoImpl根据构造方法参数名称注入constructorargnameconnectionNumvalue10beanbeaniduserDaoclasscom。itheima。dao。impl。UserDaoImplbeans构造器注入引用类型(了解)
  在bean中定义引用类型属性并提供可访问的构造方法publicclassBookDaoImplimplementsBookDao{privateBookBaobookBao;pubilcvoidsetConnectionNumber(intconnectionNumber){this。bookBaobookBao;}}
  配置中使用constructorarg标签ref属性注入简单类型数据lt;?xmlversion1。0encodingUTF8?beansxmlnshttp:www。springframework。orgschemabeansxmlns:xsihttp:www。w3。org2001XMLSchemainstancexsi:schemaLocationhttp:www。springframework。orgschemabeanshttp:www。springframework。orgschemabeansspringbeans。xsdbeanidbookServiceclasscom。itheima。service。impl。BookServiceImplconstructorargnameuserDaorefuserDaoconstructorargnamebookDaorefbookDaobeanbeans构造器注入参数配置问题(了解)
  在前面我们已经介绍了构造器的注入方法
  但如果我们在bean中的数据名称发生改变,配置就不再适配,所以提供了一些方法来解决参数配置问题:配置中使用constructorarg标签type属性设置按形参类型注入!解决形参名称的问题,与形参名不耦合beanidbookDaoclasscom。itheima。dao。impl。BookDaoImpl根据构造方法参数类型注入constructorargtypeintvalue10constructorargtypejava。lang。StringvaluemysqlbeanbeaniduserDaoclasscom。itheima。dao。impl。UserDaoImplbeanidbookServiceclasscom。itheima。service。impl。BookServiceImplconstructorargnameuserDaorefuserDaoconstructorargnamebookDaorefbookDaobean配置中使用constructorarg标签index属性设置按形参类型注入!解决参数类型重复问题,使用位置解决参数匹配beanidbookDaoclasscom。itheima。dao。impl。BookDaoImpl!根据构造方法参数位置注入constructorargindex0valuemysqlconstructorargindex1value100beanbeaniduserDaoclasscom。itheima。dao。impl。UserDaoImplbeanidbookServiceclasscom。itheima。service。impl。BookServiceImplconstructorargnameuserDaorefuserDaoconstructorargnamebookDaorefbookDaobean依赖注入方式选择
  依赖注入方式有以下选择标准:强制依赖使用构造器进行,使用setter注入有概率不进行注入导致null对象出现可选依赖使用setter注入进行,灵活性高Spring框架倡导使用构造器,第三方框架内部大多数采用构造器注入的形式进行数据初始化,相对严谨如果有必要可以两者并用,使用构造器注入完成强制依赖的注入,使用setter注入完成可选依赖的注入实际开发中根据情况分析,如果受控对象没有提供setter方法则只能采用构造器注入自己开发的模块尽量推荐setter注入依赖自动装配
  在前面我们学习了手动注入的方法,但Spring其实为我们提供了一种依赖自动装配的语法:IoC容器根据bean所依赖的资源在容器中自动查找并注入bean中的过程称为自动装配
  自动装配方式:按类型(常用)按名称按构造方法不启用
  自动装配语法:lt;?xmlversion1。0encodingUTF8?beansxmlnshttp:www。springframework。orgschemabeansxmlns:xsihttp:www。w3。org2001XMLSchemainstancexsi:schemaLocationhttp:www。springframework。orgschemabeanshttp:www。springframework。orgschemabeansspringbeans。xsdbeanclasscom。itheima。dao。impl。BookDaoImpl!autowire属性:开启自动装配,通常使用按类型装配beanidbookServiceclasscom。itheima。service。impl。BookServiceImplautowirebyTypebeans依赖自动装配特征:
  自动装配用于引用类型注入,不能对简单类型进行操作使用按类型装配时(byType)必须保障容器中相同类型的bean唯一,推荐使用使用按名称装配时(byName)必须保障容器中具有指定名称的bean,因变量名与配置耦合,不推荐使用自动装配优先级低于setter注入和构造器注入,同时出现时,自动装配配置失效依赖集合注入
  除了基本类型和引入类型外,我们有时也需要注入集合
  下面我们简单介绍一下结合的注入:数据类packagecom。itheima。dao。impl;importcom。itheima。dao。BookDao;importjava。util。;publicclassBookDaoImplimplementsBookDao{privateint〔〕array;privateListStringlist;privateSetStringset;privateMapString,Stringmap;privatePropertiesproperties;publicvoidsetArray(int〔〕array){this。arrayarray;}publicvoidsetList(ListStringlist){this。listlist;}publicvoidsetSet(SetStringset){this。setset;}publicvoidsetMap(MapString,Stringmap){this。mapmap;}publicvoidsetProperties(Propertiesproperties){this。propertiesproperties;}publicvoidsave(){System。out。println(bookdaosave。。。);System。out。println(遍历数组:Arrays。toString(array));System。out。println(遍历Listlist);System。out。println(遍历Setset);System。out。println(遍历Mapmap);System。out。println(遍历Propertiesproperties);}}!xml注入lt;?xmlversion1。0encodingUTF8?beansxmlnshttp:www。springframework。orgschemabeansxmlns:xsihttp:www。w3。org2001XMLSchemainstancexsi:schemaLocationhttp:www。springframework。orgschemabeanshttp:www。springframework。orgschemabeansspringbeans。xsdbeanidbookDaoclasscom。itheima。dao。impl。BookDaoImpl!数组注入!注意:name:对应实现类中的内部成员名称里的array等为固定词汇propertynamearrayvalue100valuevalue200valuevalue300valuearrayproperty!list集合注入propertynamelistlistvalueitcastvaluevalueitheimavaluevalueboxueguvaluevaluechuanzhihuivaluelistproperty!set集合注入propertynamesetsetvalueitcastvaluevalueitheimavaluevalueboxueguvaluevalueboxueguvaluesetproperty!map集合注入propertynamemapmapentrykeycountryvaluechinaentrykeyprovincevaluehenanentrykeycityvaluekaifengmapproperty!Properties注入propertynamepropertiespropspropkeycountrychinaproppropkeyprovincehenanproppropkeycitykaifengproppropspropertybeanbeans案例:数据源对象管理
  针对一个新的数据源对象,我们采用两步来创建bean(我们以druid为案例):导入druid坐标lt;?xmlversion1。0encodingUTF8?projectxmlnshttp:maven。apache。orgPOM4。0。0xmlns:xsihttp:www。w3。org2001XMLSchemainstancexsi:schemaLocationhttp:maven。apache。orgPOM4。0。0http:maven。apache。orgxsdmaven4。0。0。xsdmodelVersion4。0。0modelVersiongroupIdcom。itheimagroupIdspring09datasourceartifactIdversion1。0SNAPSHOTversiondependenciesdependencygroupIdorg。springframeworkgroupIdspringcontextartifactIdversion5。2。10。RELEASEversiondependency!这里导入druid坐标dependencygroupIdcom。alibabagroupIddruidartifactIdversion1。1。16versiondependencydependencygroupIdmysqlgroupIdmysqlconnectorjavaartifactIdversion5。1。47versiondependencydependenciesproject配置数据源对象作为Spring管理的beanlt;?xmlversion1。0encodingUTF8?beansxmlnshttp:www。springframework。orgschemabeansxmlns:xsihttp:www。w3。org2001XMLSchemainstancexsi:schemaLocationhttp:www。springframework。orgschemabeanshttp:www。springframework。orgschemabeansspringbeans。xsd!管理DruidDataSource对象!起id设置class地址beaniddataSourceclasscom。alibaba。druid。pool。DruidDataSource!配置基本信息propertynamedriverClassNamevaluecom。mysql。jdbc。Driverpropertynameurlvaluejdbc:mysql:localhost:3306springdbpropertynameusernamevaluerootpropertynamepasswordvalue123456beanbeans案例:加载properties文件
  这个案例我们将会介绍如何加载properties文件,并将文件带入到property基本信息中
  我们大致将步骤分为以下三步:开辟context命名空间:lt;?xmlversion1。0encodingUTF8?beansxmlnshttp:www。springframework。orgschemabeansxmlns:xsihttp:www。w3。org2001XMLSchemainstancexmlns:contexthttp:www。springframework。orgschemacontextxsi:schemaLocationhttp:www。springframework。orgschemabeanshttp:www。springframework。orgschemabeansspringbeans。xsdhttp:www。springframework。orgschemacontexthttp:www。springframework。orgschemacontextspringcontext。xsd!上述beans中的内容是我们的命名空间开辟过程在原本的xml中只有:xmlnshttp:www。springframework。orgschemabeansxmlns:xsihttp:www。w3。org2001XMLSchemainstancexsi:schemaLocationhttp:www。springframework。orgschemabeanshttp:www。springframework。orgschemabeansspringbeans。xsd在下面的内容中我们添加:xmlns:contexthttp:www。springframework。orgschemacontext并在xsi:schemaLocation中添加:http:www。springframework。orgschemacontexthttp:www。springframework。orgschemacontextspringcontext。xsd(整体从上述内容复制,然后修改末尾xsi即可)beans使用context命名空间,加载指定properties文件!2。使用context空间加载properties文件context:propertyplaceholderlocationjdbc。properties使用{}读取加载的属性值!3。使用属性占位符{}读取properties文件中的属性!说明:idea自动识别{}加载的属性值,需要手工点击才可以查阅原始书写格式beanclasscom。alibaba。druid。pool。DruidDataSourcepropertynamedriverClassNamevalue{jdbc。driver}propertynameurlvalue{jdbc。url}propertynameusernamevalue{jdbc。username}propertynamepasswordvalue{jdbc。password}bean
  除了上述的基本操作,我们在context命名空间的使用中有很多需要注意的点:不加载系统属性!因为我们的系统属性优先级定义优先级,当我们properties中的属性与系统设置属性名相同时,会优先匹配系统属性导致错误可以采用systempropertiesmode进行设置context:propertyplaceholderlocationjdbc。propertiessystempropertiesmodeNEVER加载多个properties文件!我们可以采用逗号或空格分隔加载多个properties文件context:propertyplaceholderlocationjdbc。properties,jdbc2。propertiessystempropertiesmodeNEVER加载所有properties文件!我们可以采用通配符来设置加载文件用来代替所有前缀,只保留后缀为properties即可context:propertyplaceholderlocation。propertiessystempropertiesmodeNEVER加载properties文件标准格式!我们通常以classpath表示路径,下述形式更为标准classpath:。properties:设置加载当前工程类路径中的所有properties文件context:propertyplaceholderlocationclasspath:。propertiessystempropertiesmodeNEVER从类路径或jar包中搜索并加载properties文件!我们通常以classpath来表示路径来源classpath:。properties:设置加载当前工程类路径和当前工程所依赖的所有jar包中的所有properties文件context:propertyplaceholderlocationclasspath:。propertiessystempropertiesmodeNEVER核心容器
  前面已经完成bean与依赖注入的相关知识学习,接下来我们主要学习的是IOC容器中的核心容器。
  这里所说的核心容器,大家可以把它简单的理解为ApplicationContext,接下来我们从以下几个问题入手来学习下容器的相关知识:如何创建容器?创建好容器后,如何从容器中获取bean对象?容器类的层次结构是什么?BeanFactory是什么?容器的创建方式
  案例中创建ApplicationContext的方式为(类路径下的XML配置文件):ApplicationContextctxnewClassPathXmlApplicationContext(applicationContext。xml);
  除了上面这种方式,Spring还提供了另外一种创建方式为(文件的绝对路径):ApplicationContextctxnewFileSystemXmlApplicationContext(D:workspacespringspring10containersrcmainresourcesapplicationContext。xml);Bean的三种获取方式
  方式一,就是目前案例中获取的方式:BookDaobookDao(BookDao)ctx。getBean(bookDao);
  这种方式存在的问题是每次获取的时候都需要进行类型转换
  方式二:BookDaobookDaoctx。getBean(bookDao,BookDao。class);
  这种方式可以解决类型强转问题,但是参数又多加了一个,相对来说没有简化多少。
  方式三:BookDaobookDaoctx。getBean(BookDao。class);
  这种方式就类似我们之前所学习依赖注入中的按类型注入。必须要确保IOC容器中该类型对应的bean对象只能有一个。容器类层次结构
  下面我们给出容器的层次图
  BeanFactory的使用
  使用BeanFactory来创建IOC容器的具体实现方式为:publicclassAppForBeanFactory{publicstaticvoidmain(String〔〕args){ResourceresourcesnewClassPathResource(applicationContext。xml);BeanFactorybfnewXmlBeanFactory(resources);BookDaobookDaobf。getBean(BookDao。class);bookDao。save();}}
  为了更好的看出BeanFactory和ApplicationContext之间的区别,在BookDaoImpl添加如下构造函数:publicclassBookDaoImplimplementsBookDao{publicBookDaoImpl(){System。out。println(constructor);}publicvoidsave(){System。out。println(bookdaosave。。。);}}
  如果不去获取bean对象,打印会发现:BeanFactory是延迟加载,只有在获取bean对象的时候才会去创建ApplicationContext是立即加载,容器加载的时候就会创建bean对象ApplicationContext要想成为延迟加载,只需要按照如下方式进行配置lt;?xmlversion1。0encodingUTF8?核心概念总结
  接下来我们对前面知识的一个总结,共包含如下内容:容器相关BeanFactory是IoC容器的顶层接口,初始化BeanFactory对象时,加载的bean延迟加载ApplicationContext接口是Spring容器的核心接口,初始化时bean立即加载ApplicationContext接口提供基础的bean操作相关方法,通过其他接口扩展其功能ApplicationContext接口常用初始化类ClassPathXmlApplicationContext(常用)FileSystemXmlApplicationContextbean相关
  依赖注入相关
  注解开发
  在上述的开发中,我们采用xml配置文件的形式来说依旧显得有些复杂
  这时我们就需要发挥Spring的优点:简化开发,通过注解来简化开发过程
  下面我们会通过多个方面将Bean逐步转化为注解注解开发Bean
  在前面的内容中,我们的bean在xml配置文件中装配lt;?xmlversion1。0encodingUTF8?beansxmlnshttp:www。springframework。orgschemabeansxmlns:xsihttp:www。w3。org2001XMLSchemainstancexsi:schemaLocationhttp:www。springframework。orgschemabeanshttp:www。springframework。orgschemabeansspringbeans。xsd!原生beanbeanidbookDaoclasscom。itheima。dao。impl。BookDaoImplbeans
  在后期,我们的bean可以采用注解的形式,直接在实现类中注解表示为bean
  我们采用Component定义bean,可以添加参数表示id,也可以不添加参数,后期我们采用class类的类型来进行匹配packagecom。itheima。dao。impl;importcom。itheima。dao。BookDao;importorg。springframework。stereotype。Component;importorg。springframework。stereotype。Controller;importorg。springframework。stereotype。Repository;Component定义beanComponent(bookDao)publicclassBookDaoImplimplementsBookDao{publicvoidsave(){System。out。println(bookdaosave。。。);}}packagecom。itheima。service。impl;importcom。itheima。dao。BookDao;importcom。itheima。service。BookService;importorg。springframework。stereotype。Component;importorg。springframework。stereotype。Service;Component定义beanComponentpublicclassBookServiceImplimplementsBookService{privateBookDaobookDao;publicvoidsetBookDao(BookDaobookDao){this。bookDaobookDao;}publicvoidsave(){System。out。println(bookservicesave。。。);bookDao。save();}}
  Componenty延伸出了三种类型,在实现手法上是一致,但可以具体使用于各种类中(仅用于自我识别)Controller:用于表现层bean定义Service:用于业务层bean定义Repository:用于数据层定义packagecom。itheima。dao。impl;importcom。itheima。dao。BookDao;importorg。springframework。stereotype。Component;importorg。springframework。stereotype。Controller;importorg。springframework。stereotype。Repository;Component定义beanComponent(bookDao)Repository:Component衍生注解Repository(bookDao)publicclassBookDaoImplimplementsBookDao{publicvoidsave(){System。out。println(bookdaosave。。。);}}packagecom。itheima。service。impl;importcom。itheima。dao。BookDao;importcom。itheima。service。BookService;importorg。springframework。stereotype。Component;importorg。springframework。stereotype。Service;Component定义beanComponentService:Component衍生注解ServicepublicclassBookServiceImplimplementsBookService{privateBookDaobookDao;publicvoidsetBookDao(BookDaobookDao){this。bookDaobookDao;}publicvoidsave(){System。out。println(bookservicesave。。。);bookDao。save();}}
  但是,在上述情况下,即使我们将Component的类定义为bean
  我们的xml文件是无法探测到的,所以我们需要配置相关扫描组件来扫描beanlt;?xmlversion1。0encodingUTF8?beansxmlnshttp:www。springframework。orgschemabeansxmlns:contexthttp:www。springframework。orgschemacontextxmlns:xsihttp:www。w3。org2001XMLSchemainstancexsi:schemaLocationhttp:www。springframework。orgschemabeanshttp:www。springframework。orgschemabeansspringbeans。xsdhttp:www。springframework。orgschemacontexthttp:www。springframework。orgschemacontextspringcontext。xsd!context:componentscan:表示扫描文件basepackage:表示扫描路径context:componentscanbasepackagecom。itheimabeans纯注解开发
  我们前面所提到的注解开发属于2。5的附属版本
  在Spring3。0版本,Spring就提供了纯注解开发模式,利用java类代替配置文件,开启了Spring快速开发时代
  在之前我们的xml配置文件是很繁琐的:!原生xml配置文件lt;?xmlversion1。0encodingUTF8?beansxmlnshttp:www。springframework。orgschemabeansxmlns:xsihttp:www。w3。org2001XMLSchemainstancexsi:schemaLocationhttp:www。springframework。orgschemabeanshttp:www。springframework。orgschemabeansspringbeans。xsdbeanidbookDaoclasscom。itheima。dao。impl。BookDaoImplbeans
  但是我们可以通过创建单独的类来表示配置文件:Configuration:用于声明当前类为Spring配置类ComponentScan:用于扫描类文件(类似于)packagecom。itheima。config;importorg。springframework。context。annotation。ComponentScan;importorg。springframework。context。annotation。Configuration;声明当前类为Spring配置类Configuration设置bean扫描路径,多个路径书写为字符串数组格式ComponentScan({com。itheima。service,com。itheima。dao})publicclassSpringConfig{}注意:因为该类属于配置类,我们通常单列一个文件夹来表示
  常用文件夹:config
  命名规范:SpringConfig,UserConfig。。。
  因为我们的开发不再依靠于xml配置文件,所以在主函数中的Spring容器获得方式也发生了改变:packagecom。itheima;importcom。itheima。dao。BookDao;importcom。itheima。service。BookService;importorg。springframework。context。ApplicationContext;importorg。springframework。context。support。ClassPathXmlApplicationContext;publicclassApp{publicstaticvoidmain(String〔〕args){这是我们之前的获取方式,采用路径获取xml文件ApplicationContextctxnewClassPathXmlApplicationContext(applicationContext。xml);这是新的获取方式,直接提供配置类的类型AnnotationConfigApplicationContext加载Spring配置类初始化Spring容器ApplicationContextctxnewAnnotationConfigApplicationContext(SpringConfig。class);后面操作无需变化BookDaobookDao(BookDao)ctx。getBean(bookDao);System。out。println(bookDao);按类型获取beanBookServicebookServicectx。getBean(BookService。class);System。out。println(bookService);}}注解开发Bean作用范围与管理
  既然我们的Bean开发从xml转移到注解开发,那么一些配置设置同样发生改变
  首先我们介绍Scope范围的设置方式:Scope:定义bean的作用范围packagecom。itheima。dao。impl;importcom。itheima。dao。BookDao;importorg。springframework。context。annotation。Scope;importorg。springframework。stereotype。Repository;importjavax。annotation。PostConstruct;importjavax。annotation。PreDestroy;RepositoryScope设置bean的作用范围(singleton或prototype),可以不添加默认singletonScope(singleton)publicclassBookDaoImplimplementsBookDao{publicvoidsave(){System。out。println(bookdaosave。。。);}}
  然后我们介绍一下bean生命周期的init和destroy操作:PostConstruct:定义init操作,表示构造后操作PreDestroy:定义destroy操作,表示销毁前操作依赖注入(自动装配)
  在Spring3。0中,省略掉了前面繁琐的依赖注入,我们的bean依赖注入只留下了自动装配这一操作:使用Autowired注解开启自动装配模式(按类型)当存在相同类型时,我们采用Qualifier开启按名自动装配packagecom。itheima。service。impl;importcom。itheima。dao。BookDao;importcom。itheima。service。BookService;importorg。springframework。beans。factory。annotation。Autowired;importorg。springframework。beans。factory。annotation。Qualifier;importorg。springframework。beans。factory。annotation。Value;importorg。springframework。stereotype。Service;ServicepublicclassBookServiceImplimplementsBookService{Autowired:注入引用类型,自动装配模式,默认按类型装配AutowiredQualifier:自动装配bean时按bean名称装配Qualifier(bookDao)privateBookDaobookDao;publicvoidsave(){System。out。println(bookservicesave。。。);bookDao。save();}}注意:自动装配基于反射设计创建对象并暴力反射对应属性为私有属性初始化数据,因此无需提供setter方法
  注意:自动转配建议使用无参构造方法创建对象(默认),如果不提供对应构造方法,请提供唯一的构造方法
  注意:Qualifier是基于Autowired实现的,必须保证先有Autowired才能存在Qualifier
  除了上述的bean类型装配,我们的简单类型装配依旧存在:我们采用Value的形式来配置简单类型的值packagecom。itheima。dao。impl;importcom。itheima。dao。BookDao;importorg。springframework。beans。factory。annotation。Value;importorg。springframework。stereotype。Repository;Repository(bookDao)publicclassBookDaoImplimplementsBookDao{Value:注入简单类型(无需提供set方法)Value(123)privateStringname;publicvoidsave(){System。out。println(bookdaosave。。。name);}}
  之所以使用Value的形式配置,是因为我们的类型值不一定是由手动输入的,有可能来自于Properties资源:首先我们需要在Springconfig中配置相关资源packagecom。itheima。config;importorg。springframework。context。annotation。ComponentScan;importorg。springframework。context。annotation。Configuration;importorg。springframework。context。annotation。PropertySource;ConfigurationComponentScan(com。itheima)PropertySource加载properties配置文件PropertySource({jdbc。properties})publicclassSpringConfig{}然后我们在数据层调用时,采用{}来匹配数据packagecom。itheima。dao。impl;importcom。itheima。dao。BookDao;importorg。springframework。beans。factory。annotation。Value;importorg。springframework。stereotype。Repository;Repository(bookDao)publicclassBookDaoImplimplementsBookDao{Value:注入简单类型(无需提供set方法)Value({name})privateStringname;publicvoidsave(){System。out。println(bookdaosave。。。name);}}注解开发第三方bean
  我们在实际开发中不仅仅需要对自己的bean进行管理,有时候可能需要引进其他的bean
  下面我们以Druid为例进行讲解:首先在pom。xml中导入Druid坐标lt;?xmlversion1。0encodingUTF8?projectxmlnshttp:maven。apache。orgPOM4。0。0xmlns:xsihttp:www。w3。org2001XMLSchemainstancexsi:schemaLocationhttp:maven。apache。orgPOM4。0。0http:maven。apache。orgxsdmaven4。0。0。xsdmodelVersion4。0。0modelVersiongroupIdcom。itheimagroupIdspring14annotationthirdbeanmanagerartifactIdversion1。0SNAPSHOTversiondependenciesdependencygroupIdorg。springframeworkgroupIdspringcontextartifactIdversion5。2。10。RELEASEversiondependencydependencygroupIdcom。alibabagroupIddruidartifactIdversion1。1。16versiondependencydependenciesproject使用Bean配置第三方Bean该bean同样属于config文件,我们同样放置在config文件夹下在后续我们将会讲解如何进行连接packagecom。itheima。config;importcom。alibaba。druid。pool。DruidDataSource;importcom。itheima。dao。BookDao;importorg。springframework。beans。factory。annotation。Value;importorg。springframework。context。annotation。Bean;importorg。springframework。context。annotation。Configuration;importjavax。sql。DataSource;publicclassJdbcConfig{1。定义一个方法获得要管理的对象2。添加Bean,表示当前方法的返回值是一个beanBean修饰的方法,形参根据类型自动装配BeanpublicDataSourcedataSource(){DruidDataSourcedsnewDruidDataSource();ds。setDriverClassName(com。mysql。jdbc。Driver);ds。setUrl(jdbc:mysql:localhost:3306springdb);ds。setUsername(root);ds。setPassword(123456);returnds;}}将独立的配置类加入核心配置(导入法)SpringConfigpackagecom。itheima。config;importcom。alibaba。druid。pool。DruidDataSource;importorg。springframework。context。annotation。Bean;importorg。springframework。context。annotation。ComponentScan;importorg。springframework。context。annotation。Configuration;importorg。springframework。context。annotation。Import;importjavax。sql。DataSource;ConfigurationComponentScan(com。itheima)Import:导入配置信息(如果需要多个,同样采用{}数组形式)Import({JdbcConfig。class})publicclassSpringConfig{}JdbcConfigpackagecom。itheima。config;importcom。alibaba。druid。pool。DruidDataSource;importcom。itheima。dao。BookDao;importorg。springframework。beans。factory。annotation。Value;importorg。springframework。context。annotation。Bean;importorg。springframework。context。annotation。Configuration;importjavax。sql。DataSource;ConfigurationpublicclassJdbcConfig{Bean修饰的方法,形参根据类型自动装配BeanpublicDataSourcedataSource(){DruidDataSourcedsnewDruidDataSource();配置信息returnds;}}
  注意:除了上述的导入法外还存在有其他方法,但导入法属于主流,因此我们不介绍其他流派,感兴趣的同学可以去查阅一下注解开发为第三方导入资源
  我们的第三方bean也可能需要导入部分资源,下面我们进行简单介绍:简单类型依赖注入packagecom。itheima。config;importcom。alibaba。druid。pool。DruidDataSource;importcom。itheima。dao。BookDao;importorg。springframework。beans。factory。annotation。Value;importorg。springframework。context。annotation。Bean;importorg。springframework。context。annotation。Configuration;importjavax。sql。DataSource;ConfigurationpublicclassJdbcConfig{1。定义一个方法获得要管理的对象Value(com。mysql。jdbc。Driver)privateStringdriver;Value(jdbc:mysql:localhost:3306springdb)privateStringurl;Value(root)privateStringuserName;Value(root)privateStringpassword;2。添加Bean,表示当前方法的返回值是一个beanBean修饰的方法,形参根据类型自动装配BeanpublicDataSourcedataSource(){DruidDataSourcedsnewDruidDataSource();ds。setDriverClassName(driver);ds。setUrl(url);ds。setUsername(userName);ds。setPassword(password);returnds;}}依赖类型依赖注入packagecom。itheima。config;importcom。alibaba。druid。pool。DruidDataSource;importcom。itheima。dao。BookDao;importorg。springframework。beans。factory。annotation。Value;importorg。springframework。context。annotation。Bean;importorg。springframework。context。annotation。Configuration;importjavax。sql。DataSource;publicclassJdbcConfig{BeanpublicDataSourcedataSource(BookDaobookDao){我们只需要调用即可,系统会为我们自动装配System。out。println(bookDao);}}
  引入类型注入只需要为bean定义方法设置形参即可,容器会根据类型自动装配对象
  原文链接:https:www。cnblogs。comqiuluoyuweiliangp16750470。html

每日一图湖南新年即将来临,祝大家柿柿如意!摄影邓焱萍图说近日,桂东县四都镇东水村一棵普通的柿子树,成了网红打卡点。不仅摄影师云集,更引来了周边乡镇和外地的游客驻足观看,连小鸟也纷纷前来分享甜蜜。12月中旬,我多次前往拍摄,小折叠也能有长续航,OPPOFindN2Flip内置大电池能效芯众所周知,竖折屏手机之所以能拥有独特的精巧外观,是基于空间本就有限的直板机尺寸下面再加入折叠铰链结构,进一步挤占了硬件堆叠的空间,因此目前能做到均衡全面的体验的产品少之又少,性能续继各种神药登场后,又一个资本不会放过的风口呼之欲出!对于资本市场来说,股价暴涨或者暴跌就像翻手云覆手雨那样的轻而易举,屡屡上演过山车式暴涨暴跌跳水式涨跌的惊险一幕,也在股民的眼前不断出现。这种颇有人为炒作嫌疑的涨跌,几乎遍布各个行业柳传快联想从国企到民企的改革转型与升级发展之路(二)由于,在二十世纪八十年代初期,我国全国各地各行各业的改革开放工作已经开始大刀阔斧逐渐推进。当然,村办企业乡镇企业校办企业和院办企业与所办企业等等各种类型各种性质的企业遍地开花。其中大平原(二百九十二)大堰及其它大堰及其它文韩更滨耕地分散在村子周围十八亩地老园二十九亩地家南家北这些名称被方言喊出浓浓的土腥味庄稼的长势从脑海里缓缓铺展开来大堰诗意的名字在神秘中进入儿时的记忆大人们准备好干粮吆网友称快递破洞美林被偷上热搜,顺丰回应近日有网友发文称其朋友顺丰邮寄来的快递里一盒儿童退烧药美林被偷相关话题迅速冲上热搜据这位网友自述事情是这样的她收到朋友从老家寄来的快递快递泡沫箱被掏出一个洞外包装也有破损破损处用顺总投资超19亿!虎门新一轮修路大计来啦,新建或改造道路41条人们对一座城市的印象,往往从一条道路开始。而一条条道路的升级与变迁,也见证着一座城市的不断发展与嬗变。目前,虎门正在酝酿新一轮的修路大计,涉及道路多达41条,总长度超过39公里。其新青年她把父亲留下的一本没写完的工作日志,写成了散文诗新青年纪录中国新青年第6期走你走的路山西太行山深处山西省晋城市陵川县驻村干部郭子涵2019年23岁的她绕了几个小时盘山路来到大山深处任驻村第一书记在这之前一个月她的父亲积劳成疾倒在女婿把信息发错给了岳母,岳母回复得太逗了,哈哈哈哈留下你的名字看看我们有没有缘分要说会玩还得是你啊遇到这样的情况究竟应该怎么回复才能显得霸气呢换做是你你愿意吗谁来解释下这个情绪波动怎么这么大呢没有十几年的驾龄这路都不敢走啊有什么想坐月子第十天,产妇哭着骂小姑子太过分,婆婆却这样说一个家庭,好的婆媳关系省了很多烦心事,而且这个家庭肯定会过得很幸福。如果家里存在婆媳矛盾的话,夫妻俩的感情就算再好,多少也会受到一些影响,有的夫妻还会因为婆媳关系处理不好而闹离婚,放开后,孩子在学校阳了怎么办?在新十条等新的防疫政策出台后,核酸时代与我们渐行渐远。但是,疫情并没有结束,我们依然要保护好自己的健康。对于我们家长来说,孩子的健康往往比自己还重要。这两天,周围不少妈妈都在谈论,
德媒文章欧洲航天陷入危机据德国法兰克福汇报网站3月6日报道,不久前,四名宇航员乘坐美国太空探索技术公司的猎鹰9号运载火箭成功飞往国际空间站。与此同时,欧洲航天局却仍处于危机模式。去年12月,织女星C中型运可泄露用户密码,Bitwarden密码管理器浏览器扩展发现新漏洞IT之家3月11日消息,根据安全机构FlashPoint官方博文,在密码管理器Bitwarden的浏览器扩展程序中发现了一个高危漏洞,可以泄露用户的密码信息。恶意网站可以利用该漏洞windowssoft3VMWare下ubuntu虚拟机扩容一般在VMWare安装虚拟机时,为虚拟机分配的硬盘空间会比较小,随着使用时间的增加或者开发项目后,发现虚拟机的硬盘可用容量越来越小,那应该怎么办呢?重装虚拟机?显然不是,我们只需要极简版Windows10,让老机焕新颜操作系统不断更新老机无语运行慢常死机软件不兼容那就极简系统用起来前因老电脑用户诉苦电脑买的早,配置低,现在有的软件最低要求64位系统才能安装,系统不达标,用PE可以强装为64位的,一加Ace2V,不低调的旗舰体验最初的智能手机价格一直都高高在上,后来随着更高性价比的手机出现,开启了追求手机三大件的时代,从那时起我们就忽略了手机品质的方面,毕竟低价格能使用旗舰核心是一件开心的事情,我们会说只灵动岛iPhone15标准版曝光,iPhone14即将跌至白菜价欢呼欢呼曝光iPhone15Pro机身正面,将会重新用上2。5D微曲面屏,同时屏幕黑边相较上代也将得到明显收窄。另外,iPhone15标准版也将用上灵动岛设计方案。其次是机身中框,将加入小索尼新社长对PSVR2充满信心销量预计超过500万台索尼集团的新社长十时裕树对PSVR2的成功充满信心,在最近的摩根士丹利技术会议上接受采访时表示,该设备的销量很有可能超过初代PSVR。我们很高兴在PS5上推出了PSVR2。初代PS游戏大作扎堆测试or公测?这个三月不一般!暖春已至,游戏们也如雨后春笋一般冒头,大有你来我往谁也不服谁的势劲对于游戏爱好者们来说,虽然三月也算是才刚开始,但属实已经迎来了太多的好消息!不少质量上乘出身名门的作品纷纷开启测试苹果首款3纳米A17芯片在多核测试中比A16Bionic快43A17仿生原型机的第一个性能数据已经出现,尽管我们早些时候报道说苹果会更关注电池寿命而不是原始性能,但这些数字绝对让我们震惊。在单核性能方面,A17仿生学将其前辈打得落花流水,优势支付宝二面大部分人都会答错!我是柠檬哥,专注编程知识学习和分享。欢迎关注程序员柠檬橙,编程路上不迷路私信发送1024打包下载10个G编程资源学习资料私信发送001获取阿里大神LeetCode刷题笔记私信发送0代表谈为什么有的手机越用越慢视频加载中在十四届全国人大一次会议代表通道上,全国人大代表华中科技大学计算机学院教授冯丹提到有的手机越用越慢的问题手机越用越慢卡顿,一个重要原因是手机上的文字图片视频越存越多,导致
友情链接:快好知快生活快百科快传网中准网文好找聚热点快软网