当前位置: 首页 > news >正文

淘宝客如何建设推广网站企业网站 html模板下载

淘宝客如何建设推广网站,企业网站 html模板下载,门头设计效果图大全,少女的ppt高清模板免费一、初识Spring1.1 Spring是什么Spring是一个轻量级Java开发框架#xff0c;目的是为了解决企业级应用开发的业务逻辑层和其他各层的耦合问题。它是一个分层的开源框架#xff0c;为开发Java应用程序提供全面的基础架构支持。Spring负责基础架构#xff0c;Java开发者可以专…一、初识Spring1.1 Spring是什么  Spring是一个轻量级Java开发框架目的是为了解决企业级应用开发的业务逻辑层和其他各层的耦合问题。它是一个分层的开源框架为开发Java应用程序提供全面的基础架构支持。Spring负责基础架构Java开发者可以专注于应用程序的开发。  Spring最根本的使命是简化Java开发。  Spring的功能底层都依赖于它的两个核心特性也就是依赖注入DI和面向切面编程AOP。  为了降低Java开发的复杂性Spring采取了以下4种关键策略基于POJO的轻量级和最小侵入性编程通过依赖注入和面向接口实现松耦合基于切面和惯例进行声明式编程通过切面和模板减少样板式代码。  Spring框架的核心IoC容器和AOP模块。通过IoC容器管理对象以及他们之间的耦合关系通过AOP以动态非侵入的方式增强服务。1.2 Spring的特点1、轻量级  组件大小与开销两方面而言Spring都是轻量的。完整的Spring框架可以在一个大小只有1M多的JAR文件中发布并且Spring所需的处理开销也是微不足道的。此外Spring是非侵入式典型案例Spring应用中的对象不依赖于Spring特定的类。2、控制反转  Spring通过控制反转IOC技术实现解耦。一个对象依赖的其他对象会通过被动的方式传递进来而不需要对象自己创建或者查找依赖。3、面向切面  支持切面AOP编程并且吧应用业务逻辑和系统服务区分开。4、容器  Spring包含并管理应用对象的配置和生命周期在这个意义上它是一种容器。可以配置每个bean如何被创建、销毁bean的作用范围是单例还是每次都生成一个新的实例以及他们是如何相互关联。5、框架集合  将简单的组件配置组合成为复杂的框架应用对象被申明式组合提供许多基础功能事务管理、持久化框架继承提供应用逻辑开发接口。1.3 Spring的优缺点1.3.1 优点1、方便解耦简化开发IOC  Spring就是一个工厂可以将所有对象的创建和依赖关系的维护交给Spring管理实现了松散耦合。2、AOP  Spring提供面向切面编程可以方便的实现对程序进行权限拦截、运行监控等功能把应用业务逻辑和系统服务分开。3、声明式事务的支持Transactional  只需要通过配置就可以完成对事务的管理而无需手动编程。4、方便程序的测试  Spring对Junit4支持可以通过注解方便的测试Spring程序。5、方便集成各种优秀框架  Spring不排斥各种优秀的开源框架其内部提供了对各种优秀框架的直接支持如MyBatis等。1.3.2 缺点  Spring依赖反射反射影响性能。1.4 Spring的模块组成  Spring5的模块结构图  Spring的较核心模块1、Spring core核心容器  Beans负责Bean工厂中Bean的装配所谓Bean工厂即是创建对象的工厂Bean的装配也就是对象的创建工作  Core这个模块即是负责IOC控制反转最基本的实现  ContextSpring的IOC容器因大量调用Spring Core中的函数整合了Spring的大部分功能。Bean创建好对象后由Context负责建立Bean与Bean之间的关系并维护。所以也可以把Context看成是Bean关系的集合  SpEl即Spring Expression LanguageSpring表达式语言。2、Data Access/Integration数据访问/集成  JDBC对JDBC的简单封装  ORM支持数据集成框架的封装如MybatisHibernate  OXM即Object XML Mapper它的作用是在Java对象和XML文档之间来回转换  JMS生产者和消费者的消息功能的实现  Transations事务管理。3、Web  WebSocket提供Socket通信web端的的推送功能  ServletSpring MVC框架的实现  Web包含web应用开发用到Spring框架时所需的核心类包括自动载入WebApplicationContext特性的类Struts集成类、文件上传的支持类、Filter类和大量辅助工具类  Portlet实现web模块功能的聚合。4、AOP  AOP把一个业务流程分成几部分例如权限检查、业务处理、日志记录每个部分单独处理然后把它们组装成完整的业务流程。  AOP包括aop、aspects、instrument共3个模块。5、Aspects  提供了与AspectJ的集成功能AspectJ是一个功能强大且成熟的AOP框架。6、Instrumentation设备  相当于一个检测器提供对JVM以及对Tomcat的检测。7、Messaging消息  Spring提供的对消息处理的功能。8、Test测试  在做单元测试时Spring会帮初始化一些测试过程当中需要用到的资源对象。  Spring各个模块之间的依赖关系1.5 Spring主要Package  org.springframework.coreSpring的核心工具包其他包依赖此包。  org.springframework.beans所有应用都用得到包含访问配置文件创建和管理bean等。  org.springframework.aopSpring的面向切面编程提供AOP的实现。  org.springframework.context提供在基础IOC功能上的扩展服务此外还提供许多企业级服务的支持有邮件服务、任务调度、JNDI定位EBJ集成、远程访问、缓存以及多种视图层框架的支持。  org.springframework.web.mvc包含SpringMVC应用开发所需的核心类。  org.springframework.transaction为JDBC、HIBERNATE、JDO、JPA提供一致的声明式和编程式事务管理。  org.springframework.web包含Web应用开发时用到Spring框架时所需的核心类。  org.springframework.aspectsSpring提供的对AspectJ框架的整合。  org.springframework.test对JUNIT等测试框架的简单封装。  org.springframework.asmSpring3.0开始提供自己独立的asm jar包。  org.springframework.context.supportSpring context的扩展支持用于MVC方面。  org.springframework.expressionSpring表达式语言。  org.springframework.instrument.tomcatSpring对Tomcat连接池的集成。  org.springframework.instrumentSpring对服务器的代理接口。  org.springframework.jdbc对JDBC的简单封装。  org.springframework.jms为简化jms api的使用而做的简单封装。  org.springframework.orm整合第三方的orm实现如hibernate、ibatis、jpa等。  org.springframework.oxmSpring对于Object/xml映射的支持可以让Java与xml切换。  org.springframework.portletSpring MVC的增强。  org.springframework.servlet对J2EE6.0 Servlet3.0的支持。  org.springframework.web.struts整合对struts框架的支持更方便更容易地集成Struts框架。1.7 Spring5特性  1基于JDK1.8。  2支持HTTP/2。  3Spring WebFlux响应式编程。  4支持Kotlin函数式编程。1.8 不同版本的Spring有哪些主要功能版本特性Spring2.5发布于 2007 年。这是第一个支持注解的版本。Spring3.0发布于 2009 年。它完全利用了Java5中的改进。Spring4.0发布于 2013 年。这是第一个完全支持 JAVA8 的版本。Spring5.0Spring Framework5.0的最大特点之一是响应式编程。二、IOC简介2.1 初识IOC2.1.1 IOC是什么  IoC (控制反转)是技术思想不是技术实现。IOC描述的事情Java开发领域对象的创建管理的问题。  IoC思想下开发方式我们不用自己去new对象了而是由IoC容器Spring框架去帮助我们实例化对象并且管理它我们需要使用哪个对象从IoC容器中取即可。  控制反转它把传统上由程序代码直接操控的对象的调用权交给容器通过容器来实现对象组件的装配和管理。  Spring通过一个配置文件xml表示Bean关系方式的一种描述Bean及Bean之间的依赖关系利用反射功能实例化Bean并建立Bean之间的依赖关系。Spring的IoC容器在完成这些底层工作的基础上还提供了Bean实例缓存、生命周期管理、 Bean实例代理、事件发布、资源装载等高级服务。为什么叫做控制反转  控制指的是对象创建实例化、管理的权利。  反转控制权交给外部环境了spring框架、IoC容器。2.1.2 什么是Spring IOC容器  控制反转即IoC (Inversion of Control)它把传统上由程序代码直接操控的对象的调用权交给容器通过容器来实现对象组件的装配和管理。所谓的“控制反转”概念就是对组件对象控制权的转移从程序代码本身转移到了外部容器。  Spring IOC 负责创建对象管理对象装配对象配置对象并且管理这些对象的整个生命周期。即IoC容器就是具有依赖注入功能的容器IoC容器负责实例化、定位、配置应用程序中的对象及建立这些对象间的依赖。应用程序无需直接在代码中创建相关的对象应用程序由IoC容器进行组装。  Spring IoC容器如何知道哪些是它管理的对象呢这就需要配置文件Spring IoC容器通过读取配置文件中的配置元数据通过元数据对应用中的各个对象进行实例化及装配。由IoC容器管理的那些组成应用程序的对象我们就叫它Bean Bean就是由Spring容器初始化、装配及管理的对象。  IOC容器的职责是实例化Bean把Bean关联在一起配置Bean管理Bean的整个生命周期。Spring作为IOC容器BeanFactory的简单理解  Spring启动时读取应用程序提供的Bean配置信息并在Spring容器中生成一份相应的Bean配置注册表然后根据这张注册表实例化Bean装配好Bean之间的依赖关系为上层应用提供准备就绪的运行环境。其中Bean缓存池为HashMap实现。图示2.1.3 控制反转有什么作用  1、管理对象的创建和依赖关系的维护  2、解耦。2.1.4 IoC和DI的区别  DIDependancy Injection依赖注入。IOC和DI描述的是同一件事情只不过角度不一样。  IOC控制反转 就是将原本在程序中手动创建对象的控制权交由Spring框架管理简单说就是创建对象控制权被反转到了Spring框架。  DI依赖注入在Spring框架负责创建Bean对象时动态的将依赖对象注入到Bean组件。  IoC控制反转指将对象的创建权反转到Spring容器DI依赖注入指Spring创建对象的过程中将对象依赖属性通过配置进行注入。2.1.5 Spring IoC的实现原理  Spring IoC的实现原理就是工厂模式加反射机制。图示2.2 BeanFactory与ApplicationContext  BeanFactory是Spring框架中IoC容器的顶层接口它只是用来定义那些基础功能ApplicationContext是它的一个子接口。  在初始化BeanFactory时必须为其提供一种日志框架比如使用Log4J 即在类路径下提供Log4J配置文件这样启动Spring容器才不会报错。  通常称BeanFactory为SpringIOC的基础容器ApplicationContext是容器的高级接口。ApplicationContext比BeanFactory要拥有更多的功能比如说国际化支持和资源访问xmljava配置类等。  BeanFactory可以理解为就是个HashMapKey是BeanNameValue是Bean实例。通常只提供注册put获取get这两个功能。可以称之为 “低级容器”。  ApplicationContext 可以称之为 “高级容器”因为比 BeanFactory 多了更多的功能。  BeanFactory和ApplicationContext 接口及其子类图  上图中一些类的关键作用   ClassPathXmlApplicationContext默认从类路径加载配置文件。   FileSystemXmlApplicationContext默认从文件系统中装载配置文件。   ApplicationEventPublisher让容器拥有发布应用上下文事件的功能包括容器启动事件、关闭事件等。   ResourcePatternResolver 所有ApplicationContext实现类都实现了类似于PathMatchingResourcePatternResolver的功能可以通过带前缀的Ant风格的资源文件路径装载Spring的配置文件。   LifeCycle该接口是Spring2.0加入的该接口提供了start()和stop()两个方法主要用于控制异步处理过程。在具体使用时该接口同时被ApplicationContext实现及具体Bean实现 ApplicationContext会将start/stop的信息传递给容器中所有实现了该接口的Bean以达到管理和控制JMX、任务调度等目的。   ConfigurableApplicationContext扩展于ApplicationContext它新增加了两个主要的方法 refresh()和 close()让ApplicationContext具有启动、刷新和关闭应用上下文的能力。在应用上下文关闭的情况下调用refresh()即可启动应用上下文在已经启动的状态下调用refresh()则清除缓存并重新装载配置信息而调用close()则可关闭应用上下文。2.2.1 BeanFactory和ApplicationContext的区别1、依赖关系  BeanFactory是Spring里面最顶级的接口包含了各种Bean的定义读取bean配置文档管理bean的加载、实例化控制bean的生命周期维护bean之间的依赖关系。  ApplicationContext接口作为BeanFactory的派生除了提供BeanFactory所具有的功能外还提供了更完整的框架功能继承MessageSource因此支持国际化。统一的资源文件访问方式。提供在监听器中注册bean的事件。同时加载多个配置文件。载入多个有继承关系上下文 使得每一个上下文都专注于一个特定的层次比如应用的web层。2、加载方式  BeanFactroy采用的是延迟加载形式来注入Bean的即只有在使用到某个Bean时(调用getBean())才对该Bean进行加载实例化。如果Bean的某一个属性没有注入BeanFacotry加载后直至第一次使用调用getBean方法才会抛出异常。  ApplicationContext它是在容器启动时一次性创建了所有的Bean。这样在容器启动时我们就可以发现Spring中存在的配置错误这样有利于检查所依赖属性是否注入。ApplicationContext启动后预载入所有的单实例Bean通过预载入单实例bean,确保当你需要的时候你就不用等待因为它们已经创建好了。  相对于基本的BeanFactoryApplicationContext 唯一的不足是占用内存空间。当应用程序配置Bean较多时程序启动较慢。3、底层资源的访问  ApplicationContext扩展了ResourceLoader(资源加载器)接口从而可以用来加载多个Resource而BeanFactory是没有扩展ResourceLoader。  绝大多数情况下建议使用ApplicationContext因为ApplicationContext包含BeanFactory的所有功能因此通常建议优先于BeanFactory使用它。4、创建方式  BeanFactory通常以编程的方式被创建ApplicationContext还能以声明的方式创建如使用ContextLoader。5、注册方式  BeanFactory和ApplicationContext都支持BeanPostProcessor、BeanFactoryPostProcessor的使用但两者之间的区别是BeanFactory需要手动注册而ApplicationContext则是自动注册。2.2.2 ApplicationContext的实现类ApplicationContext常用实现类作用AnnotationConfigApplicationContext 常用从一个或多个基于Java的配置类中加载上下文定义适用于Java注解的方式纯注解模式下启动Spring容器ClassPathXmlApplicationContext常用从类路径下的一个或多个xml配置文件中加载上下文定义适用于xml配置的方式 需要正确设置classpath因为这个容器将在classpath里找bean配置FileSystemXmlApplicationContext 常用从文件系统下的一个或多个xml配置文件中加载上下文定义也就是说系统盘符中加载xml配置文件XML Bean 配置文件的全路径名必须提供给它的构造函数AnnotationConfigWebApplicationContext专门为web应用准备的适用于注解方式XmlWebApplicationContext从Web应用下的一个或多个xml配置文件加载上下文定义适用于xml配置方式显示详细信息  ClassPathXmlApplicationContext和FileSystemXmlApplicationContext的路径加载区别ClassPathXmlApplicationContext默认文件路径是src下那一级FileSystemXmlApplicationContext 默认获取的是项目路径,默认文件路径是项目名下一级与src同级。三、通过XML方式创建Bean3.1 在XML中通过构造器方式创建Bean的3种方式【使用较少】  Spring Bean是那些形成Spring应用的Java对象它们被Spring IOC容器初始化、装配和管理。3.1.1 构造器实例化Bean  假设有一个Person类有name、age两个属性通过构造器的方法的配置方式示例 beanidpersonclasscom.spring.demo.Personconstructor-argnamenamevalue等风的草/constructor-argnameagevalue21//bean3.1.2 静态工厂实例化Bean  当采用静态工厂方法创建bean时除了需要指定class属性外还需要通过factory-method属性来指定创建bean实例的工厂方法。  假设有这样的静态工厂PersonStaticFactory类 publicstaticPersoncreateInstance(){returnnewPerson();}  配置文件class:指定静态工厂类factory-method:指定哪个方法是工厂方法 beanidpersonclasscom.spring.demo.PersonStaticFactory factory-methodcreateInstanceconstructor-argnamenamevalue等风的草/constructor-argnameagevalue21//bean  这种方式获取Bean的方式也和通过构造器方法创建Bean的方式类似示例ApplicationContext applicationContext newClassPathXmlApplicationContext(xmlPath);System.out.println(applicationContext .getBean(person));3.1.3 实例工厂实例化bean  示例 publicclassInstanceFactory{publicPersoncreateInstance(){returnnewPerson();}}  配置文件示例factory-bean指定使用哪个工厂实例。factory-method指定使用哪个工厂实例的方法 beanidinstancefactoryclasscom.spring.demo.InstanceFactory/beanidpersonInstancefactory-beaninstancefactoryfactory-methodcreateInstance/3.2 在XML中通过有参构造方法和无参构造方法创建Bean【使用较少】  构造方法分有参和无参2种因此通过构造方法来创建Bean自然也分为2种。3.2.1 通过无参构造方法来创建Bean  实体类publicclassHello{privateString name;publicStringgetName(){return name;}publicvoidsetName(String name){this.name name;}publicvoidshow(){System.out.println(Hello, name );}}  Spring的配置文件在src目录下命名为beans.xml?xml version1.0 encodingUTF-8?beansxmlnshttp://www.springframework.org/schema/beansxmlns:xsihttp://www.w3.org/2001/XMLSchema-instancexsi:schemaLocationhttp://www.springframework.org/schema/beanshttp://www.springframework.org/schema/beans/spring-beans.xsdbeanidhelloclasscom.spring.test.Hello/bean/beans  测试类publicclassSpringTest{publicstaticvoidmain(String[] args){test();}publicstaticvoidtest(){//解析beans.xml文件 , 生成管理相应的Bean对象ApplicationContext context newClassPathXmlApplicationContext(beans.xml);//getBean : 参数即为spring配置文件中bean的idHello hello (Hello) context.getBean(hello);//Hello,nullhello.show();}}3.2.2 通过有参构造方法来创建Bean  通过有参构造方法来创建对象的方式有三种示例!-- 第一种根据index参数下标设置 --beaniduser1classcom.test.pojo.User!-- index指构造方法 , 下标从0开始 --constructor-argindex0valuezhangsan//bean!-- 第二种根据参数名字设置 --beaniduser2classcom.test.pojo.User!-- name指参数名 --constructor-argnamenamevaluelisi//bean!-- 第三种根据参数类型设置 --beaniduser3classcom.test.pojo.Userconstructor-argtypejava.lang.Stringvaluewangwu//bean3.3 constructor-arg标签属性  在使用构造函数注入时涉及的标签是constructor-arg该标签有如下属性name用于给构造函数中指定名称的参数赋值。index用于给构造函数中指定索引位置的参数赋值。value用于指定基本类型或者String类型的数据。ref用于指定其他Bean类型的数据。写的是其他bean的唯一标识。3.4 在XML中通过set注入属性的方法来创建Bean【使用较少】  在上面的两种创建Bean的方式中要求Bean有对象的构造方法那么有没有其他比较灵活的注入方式呢当然是有的就是set方法的注入方式这种方式要求Bean有对应的setXXX方法。  配置文件示例beanidhelloclasscom.spring.test.HellopropertynamenamevalueSpring//bean3.5 在XML中通过set方式注入不同类型数据【使用较少】  通过set的方式注入最普通的字符串来创建对象。其实除了字符串还可以通过set的放入注入其他数据。3.5.1 注入其他对象beanidaddrclasscom.test.pojo.Addresspropertynameaddressvalue重庆//beanbeanidstudentclasscom.test.pojo.Studentpropertynamenamevalue小明/propertynameaddressrefaddr//bean3.5.2 注入数组beanidstudentclasscom.test.pojo.Studentpropertynamenamevalue小明/propertynameaddressrefaddr/propertynamebooksarrayvalue英雄志/valuevalue沧浪之水/valuevalue梦的解析/value/array/property/bean3.5.3 注入List!--注入字符串List--propertynameinterestlistvalue听歌/valuevalue看电影/valuevalue爬山/value/list/property!--注入对象List--propertynameempListlistrefbeanemp1/refbeanemp2//list/property3.5.4 注入Mappropertynamestorymapentrykey余华value活着/entrykey东野圭吾value白夜行//map/propertypropertynameempMapmapentrykey1value-refemp1/entrykey2value-refemp2//map/property3.5.5 注入Setpropertynamemoviesetvalue兹山鱼谱/valuevalue浪客剑心/value/set/propertypropertynameempSetssetrefbeanemp1/refbeanemp2//set/property3.5.6 注入Null  在Spring中不仅可以注入一个Null值也可以注入空字符串。propertynamewifenull//propertypropertynamenamenull/null/property3.5.7 注入属性  用于注入键值对键和值都只能为String类型。propertynameinfopropspropkey学号20190604/proppropkey性别男/proppropkey姓名小明/prop/props/property3.6 property标签属性  在使用set方法注入时需要使用property标签该标签属性如下name指定注入时调用的set方法名称。注不包含set这三个字母druid连接池指定属性名称value指定注入的数据。它支持基本类型和String类型。ref指定注入的数据。它支持其他bean类型。写的是其他bean的唯一标识。3.7 构造器依赖注入和Setter方法注入的区别1、Setter方法注入  1、设值注入需要该Bean包含这些属性的setter方法。  2、对于复杂的依赖关系如果采用构造注入会导致构造器过于臃肿。Spring在创建Bean实例时需要同时实例化器依赖的全部实例因而导致性能下降。而使用设值注入则能避免这些问题。  3、尤其是在某些属性可选的情况下多参数的构造器显得更加笨重。2、构造注入  1、构造注入需要该Bean包含带有这些属性的构造器。  2、构造注入可以在构造器中决定依赖关系的注入顺序优先依赖的优先注入。例如组件中其他依赖关系的注入常常要依赖于DataSrouce的注入。采用构造注入可以在代码中清晰的决定注入顺序。  3、对于依赖关系无需变化的Bean构造注入更有用处。因为没有Setter方法所有的依赖关系全部在构造器内设定。因此无需担心后续的代码对依赖关系产生破坏。  4、依赖关系只能在构造器中设定则只有组件的创建者才能改变组件的依赖关系。对组件的调用者而言组件内部的依赖关系完全透明更符合高内聚的原则。  在两种方式的选择上最好的解决方案是用构造器参数实现强制依赖setter方法实现可选依赖。3.8 Bean标签属性  在基于XML的IoC配置中bean标签是最基础的标签。它表示了IoC容器中的1个对象。换句话说如果1个对象想让spring管理在XML的配置中都需要使用此标签配置Bean标签的属性如下id属性 用于给Bean提供1个唯一标识。在1个标签内部标识必须唯一。class属性用于指定创建Bean对象的全限定类名。name属性用于给Bean提供1个或多个名称。多个名称用空格分隔。factory-bean属性用于指定创建当前bean对象的工厂Bean的唯一标识。当指定了此属性之后class属性失效。factory-method属性用于指定创建当前bean对象的工厂方法如配合factory-bean属性使用则class属性失效。如配合class属性使用则方法必须是static的。scope属性用于指定bean对象的作用范围。通常情况下就是singleton。当要用到多例模式时可以配置为prototype。init-method属性用于指定Bean对象的初始化方法此用法会在Bean对象装配后调用。必须是1个无参方法。destory-method属性用于指定bean对象的销毁方法此方法会在Bean对象销毁前执行。它只能为scope是singleton时起作用。四、通过注解方式创建Bean  在实际开发中纯XML管理Bean的方式已经很少用了更多的时候用的是注解的方式。  xml中标签与注解的对应关系示例xml形式对应的注解形式BeanComponent(“accountDao”)注解加在类上Bean的id属性内容直接配置在注解后如果不配置默认定义个这个bean的id为类的类名首字母小写另外针对分层代码开发提供了Componenet的三种别名Controller、Service、Repository分别用于控制层类、服务层类、dao层类的bean定义这四个注解的用法完全一样只是为了更清晰的区分Scope属性Scope(“prototype”)默认单例注解加在类上  其他的一些较常用的注解Configuratio表明当前类是一个配置类。ComponentScan替代 context:component-scan。Value对变量赋值可以直接赋值也可以使用 ${} 读取资源配置文件中的信息。Bean将方法返回对象加入Spring IOC容器。Component的简单使用  配置文件中需要添加context:component-scan配置示例 context:component-scanbase-packagecom.spring.test/  Component的使用简单示例Component(user)//相当于配置文件中 bean iduser class当前注解的类/publicclassUser{String name 自己;}  测试代码 publicstaticvoidtest(){ApplicationContext context newClassPathXmlApplicationContext(beans.xml);User user (User) context.getBean(user);//自己System.out.println(user.name);}Value的简单使用  可以不用提供set方法直接在直接名上添加value(“值”)示例Component(user)// 相当于配置文件中 bean iduser class当前注解的类/publicclassUser{Value(自己)// 相当于配置文件中 property namename value自己/publicString name;}  如果提供了set方法在set方法上添加value(“值”)示例Component(user)publicclassUser{publicString name;Value(自己)publicvoidsetName(String name){this.name name;}}4.1 Bean自动装配的5种方式  Bean装配是指在Spring容器中把Bean组装到一起前提是容器需要知道Bean的依赖关系如何通过依赖注入来把它们装配到一起。  Spring装配包括手动装配和自动装配手动装配是有基于xml装配、构造方法、setter方法等。  自动装配有五种自动装配的方式可以用来指导Spring容器用自动装配方式来进行依赖注入。  先准备几个实体类 publicclassCat{publicvoidshout(){System.out.println(喵~);}}publicclassDog{publicvoidshout(){System.out.println(汪~);}}publicclassUser{privateCat cat;privateDog dog;privateString str;publicCatgetCat(){return cat;}publicvoidsetCat(Cat cat){this.cat cat;}publicDoggetDog(){return dog;}publicvoidsetDog(Dog dog){this.dog dog;}publicStringgetStr(){return str;}publicvoidsetStr(String str){this.str str;}}4.1.1 no  默认的方式是不进行自动装配的通过手工设置ref属性来进行装配bean。示例beaniddogclasscom.spring.test.Dog/beanidcatclasscom.spring.test.Cat/beaniduserclasscom.spring.test.Userpropertynamecatrefcat/propertynamedogrefdog/propertynamestrvaluetest//bean  测试 publicstaticvoidtest(){ApplicationContext context newClassPathXmlApplicationContext(beans.xml);User user (User) context.getBean(user);//喵~user.getCat().shout();//汪~user.getDog().shout();}4.1.2 byName  通过Bean的名称进行自动装配如果一个Bean的property与另一个Bean的name相同就进行自动装配。  示例beaniduserclasscom.spring.test.UserautowirebyNamepropertynamestrvaluetest//bean  测试代码 publicstaticvoidtest(){ApplicationContext context newClassPathXmlApplicationContext(beans.xml);User user (User) context.getBean(user);//testSystem.out.println(user.getStr());}  该模式表示根据Property的Name自动装配如果一个Bean的name和另一个Bean中的Property的name相同则自动装配这个Bean到Property中。  也就是说当一个Bean节点带有autowirebyName的属性时将查找其类中所有的set方法名获得将set去掉并且首字母小写的字符串然后去spring容器中寻找是否有此字符串名称id的对象。如果有就取出注入如果没有就报空指针异常。4.1.3 byType  通过参数的数据类型进行自动装配。使用autowirebyType时首先需要保证同一类型的对象在Spring容器中唯一。如果不唯一会报不唯一的异常NoUniqueBeanDefinitionException。  如果照下面的配置就会报异常因为有两个同类型的Beanbeaniddogclasscom.spring.test.Dog/beanidcatclasscom.spring.test.Cat/beanidcat2classcom.spring.test.Cat/beaniduserclasscom.spring.test.UserautowirebyTypepropertynamestrvaluetest//bean  删掉id为cat或cat2的Bean则代码可以正常运行示例 publicstaticvoidtest(){ApplicationContext context newClassPathXmlApplicationContext(beans.xml);User user (User) context.getBean(user);//testSystem.out.println(user.getStr());}4.1.4 constructor  利用构造函数进行装配并且构造函数的参数通过byType进行装配。这个方式类似于byType但是要提供给构造器参数如果没有确定的带参数的构造器参数类型将会抛出异常。  先在User实体类中加入一个构造方法 publicUser(Cat cat){this.cat cat;}  然后配置文件改为beanidcatclasscom.spring.test.Cat/beaniduserclasscom.spring.test.Userautowireconstructor/bean  测试 publicstaticvoidtest(){ApplicationContext context newClassPathXmlApplicationContext(beans.xml);User user (User) context.getBean(user);//喵~user.getCat().shout();}4.1.5 autodetect  该模式自动探测使用构造器自动装配或者byType自动装配。首先会尝试找合适的带参数的构造器如果找到就是用构造器自动装配如果在Bean内部没有找到相应的构造器或者是无参构造器容器就会自动选择byTpe的自动装配方式。4.2 开启自动装配的注解  Jdk1.5开始支持注解Spring2.5开始全面支持注解。  要使用注解需要在配置文件里加上context:annotation-config/用来开启注解支持。  配置文件中关于Bean的关键配置示例 context:annotation-config/beanidcatclasscom.spring.test.Cat/beaniduserclasscom.spring.test.User/  此时就可以在代码中使用Autowired注解自动获取到对应的对象了这也是实际项目中常见的做法。示例 publicclassUser{AutowiredprivateCat cat;//其他代码}4.3 Autowired和Resource4.3.1 Autowired注解  Autowired注解用来自动装配指定的bean。  Autowired注解原理在启动spring IoC时容器自动装载了一个AutowiredAnnotationBeanPostProcessor后置处理器当容器扫描到Autowied、Resource或Inject时就会在IoC容器自动查找需要的bean并装配给该对象的属性。在使用Autowired时首先在容器中查询对应类型的bean如果查询结果刚好为一个就将该bean装配给Autowired指定的数据如果查询的结果不止一个那么Autowired会根据名称来查找如果上述查找的结果为空那么会抛出异常。解决方法时使用requiredfalse。 示例Autowired(requiredfalse)。  Autowired(requiredfalse) 使用说明当值为false时对象可以为null当值为true时对象必须存对象不能为null。  Autowired可用于构造函数、成员变量、Setter方法。Autowired的作用是自动注入Bean。最常见的使用示例publicclassUserService{//相当于直接给userDao变量实例化AutowiredprivateUserDao userDao;}  如上代码所示Spring容器会找到类型为UserDao的类然后将其注入进来。这样会产生一个问题当一个类型有多个Bean值的时候会造成无法选择具体注入哪一个的情况Spring容器在启动时也会抛出BeanCreationException。这个时候可以配合Qualifier使用Qualifier告诉spring具体去装配哪个对象。  当使用AutoWired注解的时候自动装配的时候是根据类型在上面的例子中即类型为UserDao的类来装配的如果只找到一个UserDao类型的类则直接进行赋值如果没有找到UserDao类型的类则直接抛出异常如果找到多个UserDao类型的类那么会按照变量名此处的变量名为类名首字母小写作为id继续匹配 1匹配上直接进行装配 2如果匹配不上则直接报异常。还可以不使用变量名使用Qualifier注解来指定id的名称当使用Qualifier注解的时候也会有两种情况 1找到则直接装配 2找不到就会报错。  Qualifier和Autowired结合使用的示例publicclassUserService{AutowiredQualifier(nameuserDao1)privateUserDao userDao;}4.3.2 Resource注解  Resource注解也可以完成自动注入其自动注入规律如果同时指定了name和type则从Spring上下文中找到唯一匹配的bean进行装配找不到则抛出异常。如果指定了name则从上下文中查找名称id匹配的bean进行装配找不到则抛出异常。如果指定了type则从上下文中找到类似匹配的唯一Bean进行装配找不到或是找到多个都会抛出异常。如果既没有指定name也没有指定type则自动按照byName方式进行装配。如果没有匹配则回退为一个原始类型进行匹配如果匹配则自动装配。  Resource的使用示例publicclassUser{//优先注入name为cat2的BeanResource(name cat2)privateCat cat;//其他代码}  Resource在Jdk11中已经移除如果要使用需要单独引入jar包。示例dependencygroupIdjavax.annotation/groupIdartifactIdjavax.annotation-api/artifactIdversion1.3.2/version/dependency4.3.3 Autowired和Resource之间的区别1、Autowired  Autowired为Spring提供的注解。  Autowired默认按类型装配默认情况下必须要求依赖对象必须存在如果要允许null值可以设置它的required属性为false如果想使用按照名称byName来装配可以结合Qualifier注解一起使用。示例publicclassTestServiceImpl{AutowiredQualifier(userDao)privateUserDao userDao;}2、Resource  Resourc是jdk提供的注解。  Resource默认按照ByName自动注入。示例publicclassUserService{ResourceprivateUserDao userDao;Resource(namestudentDao)privateStudentDao studentDao;Resource(typeTeacherDao)privateTeacherDao teacherDao;Resource(namemanDao,typeManDao)privateManDao manDao;}3、总结AutoWiredResource来源springJdk默认的Bean匹配方式按类型按名称使用范围只适合spring框架扩展性更好五、在Spring中创建Bean的一些相关问题5.1 Bean的作用域  当定义一个Bean在Spring里我们还能给这个bean声明一个作用域。它可以通过Bean定义中的scope属性来定义。Spring框架支持以下五种Bean的作用域类别说明注解singleton默认值 容器初始时创建 bean 实例 在整个容器的生命周期内只创建这一个beanScope(“singleton”)prototype容器初始化时不创建bean的实例而在每次请求时都创建一个新的Bean的实例Scope(“prototype”)request在每一次http请求时会创建一个实例该实例仅在当前http request有效Scope(“request”)session在每一次http请求时会创建一个实例该实例仅在当前http session有效Scope(“session”)globalSession全局Session类似于标准的HTTP Session作用域不过它仅仅在基于portlet的web应用中才有意义。SessionScope显示详细信息   Spring4.x的版本中包含两种作用域request和session作用域不过这两种作用域几乎不用因此在5版本的时候被淘汰了。  在这几类作用域中最常用的是Singleton和Prototype。一般情况下对有状态的bean使用prototype作用域而对无状态的bean使用singleton作用域。1、Singleton  当一个Bean的作用域为Singleton那么Spring IoC容器中只会存在一个共享的Bean实例并且所有对Bean的请求只要id与该Bean定义相匹配则只会返回Bean的同一实例。  该模式在多线程下是不安全的。  当创建容器时对象就被创建了。只要容器在对象一直活着。当销毁容器时对象就被销毁了。一句话总结单例模式的Bean对象生命周期与容器相同。  示例beanidhelloclasscom.spring.test.HelloscopesingletonpropertynamenamevalueSpring//bean  测试 publicstaticvoidtest(){//解析beans.xml文件 , 生成管理相应的Bean对象ApplicationContext context newClassPathXmlApplicationContext(beans.xml);//getBean : 参数即为spring配置文件中bean的idHello hello1 (Hello) context.getBean(hello);Hello hello2 (Hello) context.getBean(hello);//trueSystem.out.println(hello1hello2);}2、Prototype  当一个Bean的作用域为Prototype表示一个Bean定义对应多个对象实例。Prototype作用域的Bean会导致在每次对该Bean请求将其注入到另一个bean中或者以程序的方式调用容器的getBean()方法时都会创建一个新的Bean实例。  当使用对象时创建新的对象实例。只要对象在使用中就一直活着。当对象长时间不用时被Java的垃圾回收器回收了。一句话总结多例模式的bean对象spring框架只负责创建不负责销毁。  一般来说对有状态的bean使用prototype作用域而对无状态的bean使用singleton作用域。  示例beanidhelloclasscom.spring.test.HelloscopeprototypepropertynamenamevalueSpring//bean  测试 publicstaticvoidtest(){//解析beans.xml文件 , 生成管理相应的Bean对象ApplicationContext context newClassPathXmlApplicationContext(beans.xml);//getBean : 参数即为spring配置文件中bean的idHello hello1 (Hello) context.getBean(hello);Hello hello2 (Hello) context.getBean(hello);//falseSystem.out.println(hello1hello2);}3、Request  当一个Bean的作用域为Request表示在一次HTTP请求中一个Bean定义对应一个实例即每个HTTP请求都会有各自的Bean实例而且该bean仅在当前Http Request内有效,当前Http请求结束该bean实例也将会被销毁。该作用域仅在基于Web的Spring ApplicationContext情形下有效。  示例 beanidloginActionclasscn.csdn.LoginActionscoperequest/4、Session  当一个Bean的作用域为Session表示在一个HTTP Session中一个Bean定义对应一个实例。每一次Session请求创建新的实例而不同的实例之间不共享属性且实例仅在自己的Session请求内有效请求结束则实例将被销毁。该作用域仅在基于Web的Spring ApplicationContext情形下有效。示例 beaniduserPreferencesclasscom.foo.UserPreferencesscopesession/5、Global Session  当一个bean的作用域为Global Session表示在一个全局的HTTP Session中一个bean定义对应一个实例。典型情况下仅在使用portlet context的时候有效。该作用域仅在基于Web的Spring ApplicationContext情形下有效。  默认的Spring Bean 的作用域是Singleton。使用Prototype作用域时频繁创建和销毁Bean会带来很大的性能开销。5.2 实体类常用的注解  主要用到的插件是Lombok使用Lombok注解目的和作用就在于不用再去写经常反复去写的如GetterSetterConstructor等一些代码。常用的注解有以下几个Data使用这个注解就不用再去手写Getter、Setter、equals、hasCode、toString等方法注解后在编译时会自动加进去。AllArgsConstructor使用后添加一个构造函数该构造函数含有所有已声明字段属性参数NoArgsConstructor使用后创建一个无参构造函数Builder关于Builder较为复杂一些Builder的作用之一是为了解决在某个类有很多构造函数的情况也省去写很多构造函数的麻烦在设计模式中的思想是用一个内部类去实例化一个对象避免一个类出现过多构造函数Setter/Getter为相应的属性自动生成Getter/Setter方法。ToString生成一个toString()方法默认情况下会输出类名、所有属性会按照属性定义顺序用逗号来分割。ToString的使用效果示例OverridepublicStringtoString(){returnSquare(supersuper.toString(), widththis.width , heightthis.height );}}  Data、AllArgsConstructor、NoArgsConstructor、Builder使用示例Data//生成getter,setter等函数AllArgsConstructor//生成全参数构造函数NoArgsConstructor//生成无参构造函数Builderpublicclass test1 {String name;String age;String sex;}  Builder使用示例 publicstaticvoidmain(String[] args){//使用Builder注解后可以直接通过Builder设置字段参数test1 t1new test1.test1Builder().name(wang).age(12).sex(man).build();System.out.println(name ist1.getName()\nage is :t1.getAge());}5.3 Bean  该注释的属性的名称和语义类似于Spring XML模式中bean的元素的名称和语义。Bean指示方法产生一个由Spring容器管理的bean。  使用示例ConfigurationpublicclassDataBaseConfig{Bean(dataSource)publicDataSourcegetDataSource(){DataSource dataSource newDataSource();dataSource.setUserId(jingsi);dataSource.setPassword(123456);dataSource.setUrl(www);return dataSource;}}RestControllerpublicclassIndexController{AutowiredprivateUser user;AutowiredprivateDataSource dataSource;GetMapping(value index)publicStringindex(){returnhello worlddataSource:dataSource;}}5.4 Spring框架中的单例Bean是线程安全的吗  Spring框架中的单例Bean不是线程安全的。Spring中的Bean默认是单例模式但并没有对单例Bean进行多线程的封装处理。  实际上大部分的Spring Bean并没有可变的状态比如Service类和DAO类所以在某种程度上Spring的单例bean是线程安全的。  如果某个Bean有多种状态的话就需要自行保证线程安全最简单的解决办法就是将多态Bean的作用域设置为“prototype”。  如果单例Bean是一个无状态Bean也就是线程中的操作不会对Bean的成员执行查询以外的操作那么这个单例Bean是线程安全的。比如Spring MVC的Controller、Service、Dao等这些Bean大多是无状态的只关注于方法本身。  对于有状态的BeanSpring官方提供的Bean一般提供了通过ThreadLocal去解决线程安全的方法比如RequestContextHolder、TransactionSynchronizationManager、LocaleContextHolder等。有状态对象  就是有实例变量的对象可以保存数据是非线程安全的。每个用户有自己特有的一个实例在用户的生存期内Bean保持了用户的信息即“有状态”。一旦用户灭亡调用结束或实例结束Bean的生命期也告结束。无状态对象  就是没有实例变量的对象不能保存数据是不变类是线程安全的。Bean一旦实例化就被加进会话池中各个用户都可以共用。即使用户已经消亡Bean的生命期也不一定结束它可能依然存在于会话池中供其他用户调用。由于没有特定的用户那么也就不能保持某一用户的状态所以叫无状态Bean。5.6 Spring如何处理线程并发问题  在一般情况下只有无状态的Bean才可以在多线程环境下共享在Spring中绝大部分Bean都可以声明为Singleton作用域Spring对一些Bean中非线程安全状态采用ThreadLocal进行处理解决线程安全问题。  ThreadLocal和线程同步机制都是为了解决多线程中相同变量的访问冲突问题。同步机制采用了“时间换空间”的方式仅提供一份变量不同的线程在访问前需要获取锁没获得锁的线程则需要排队。而ThreadLocal采用了“空间换时间”的方式。  ThreadLocal会为每一个线程提供一个独立的变量副本从而隔离了多个线程对数据的访问冲突。因为每一个线程都拥有自己的变量副本从而也就没有必要对该变量进行同步了。ThreadLocal提供了线程安全的共享对象在编写多线程代码时可以把不安全的变量封装进ThreadLocal。5.6 Spring实现单例用到了什么集合对象  Spring对Bean实例的创建是采用单例注册表的方式进行实现的而这个注册表的缓存是ConcurrentHashMap 对象。5.7 循环注入/循环依赖  什么是循环注入举个列子有一个类AA有一个构造器里面的参数是类B类B里面有个构造器参数是类C类C里面有个构造器参数是类A。其实引用循环了A里面有B的引用B里面有C的引用C里面又有A的引用。  当用Spring加载A的时候Spring的流程是这样的Spring创建类A的实例对象首先去当前创建池中去查找当前类A的实例对象是否在创建如果发明没有创建则准备其构造器需要的参数B然后把创建A的标识放入当前创建池中。Spring 创建B首先去当前创建池中去查找当前B是否在创建如果发现没有创建则准备其构造器需要的参数C然后把创建B的标识放入当前创建池中。Spring 创建C首先去当前创建池中去查找当前C是否在创建如果发现没有创建则准备其构造器需要的参数A然后把创建C的标识放入当前创建池中。Spring 创建C需要的A这个时候会发现在当前创建池中已经有A的标识A正在创建中则抛出 BeanCurrentlyInCreationException。5.7.1 什么是循环依赖  循环依赖其实就是循环引用也就是两个或者两个以上的 Bean 互相持有对方最终形成闭环。比如A依赖于BB依赖于CC依赖于A。  这里不是函数的循环盗用是对象的相互依赖关系。循环调用其实就是一个死循环除非有终结条件。  Spring中循环依赖场景有构造器的循环依赖构造器注入、Field属性的循环依赖set注入。  构造器的循环注入是没有办法解决的所以只能避免。因此不要使用基于构造函数的依赖注入可以通过以下方式解决在字段上使用Autowired注解让Spring决定在合适的时机注入用基于setter方法的依赖注入。  在解决属性循环依赖时Spring采用的是提前暴露对象的方法。5.7.2 循环依赖处理机制单例Bean构造器参数循环依赖无法解决prototype原型Bean循环依赖无法解决  对于原型bean的初始化过程中不论是通过构造器参数循环依赖还是通过setXxx方法产生循环依赖Spring都会直接报错处理。  AbstractBeanFactory.doGetBean()方法 if(isPrototypeCurrentlyInCreation(beanName)){thrownewBeanCurrentlyInCreationException(beanName);}protectedbooleanisPrototypeCurrentlyInCreation(String beanName){Object curVal this.prototypesCurrentlyInCreation.get();return(curVal !null(curVal.equals(beanName)||(curVal instanceofSet((Set?)curVal).contains(beanName))));}  在获取bean之前如果这个原型bean正在被创建则直接抛出异常。原型bean在创建之前会进行标记这个beanName正在被创建等创建结束之后会删除标记 try{//创建原型bean之前添加标记beforePrototypeCreation(beanName);//创建原型beanprototypeInstance createBean(beanName, mbd, args);}finally{//创建原型bean之后删除标记afterPrototypeCreation(beanName);}  总结Spring不支持原型bean的循环依赖。单例Bean通过setXxx或者Autowired进行循环依赖  Spring的循环依赖的理论依据基于Java的引用传递当获得对象的引用时对象的属性是可以延后设置的但是构造器必须是在获取引用之前。  Spring通过setXxx或者Autowired方法解决循环依赖其实是通过提前暴露1个ObjectFactory对象来完成的简单来说ClassA在调⽤构造器完成对象初始化之后在调用ClassA的setClassB⽅法之前就把ClassA实例化的对象通过ObjectFactory提前暴露到Spring容器中。  1Spring容器初始化ClassA通过构造器初始化对象后提前暴露到Spring容器。  2ClassA调用setClassB方法Spring先尝试从容器中获取ClassB此时ClassB不存在Spring容器中。  3Spring容器初始化ClassB同时也会将ClassB提前暴露到Spring容器中。  4ClassB调用setClassA方法Spring从容器中获取ClassA 因为第1步中已经提前暴露了ClassA因此可以获取到ClassA实例。ClassA通过spring容器获取到ClassB完成了对象初始化操作。  5这样ClassA和ClassB都完成了对象初始化操作解决了循环依赖问题。
http://www.dnsts.com.cn/news/190003.html

相关文章:

  • 登封市城乡建设路网站少儿编程网课平台哪个好
  • 邮件表头图片网站襄阳微网站建设
  • 网站自适应手机转码医院网站前置审批文件
  • 宝塔网站搭建教程wordpress与
  • 怎么百度做网站外贸询单
  • 想成为网站设计师要怎么做python编程下载
  • 有哪些网站可以做笔译网站超市源码哪个好
  • 企业为什么需要搭建一个网站河北建设厅官方网站
  • 淘宝客网站跳转单品爱心捐赠网站怎么做
  • 昆明网站建设优化技术买衣服的网站排行榜
  • 网站做全景图预览沐风wordpress
  • 国外优惠卷网站怎么做网站title 在哪里设置
  • 做蛋糕比较火的网站大学生旅游网站设计框架
  • 设计网站vcg企业品牌营销策划
  • 做ppt兼职网站有哪些微信官方商城小程序
  • html5响应式网站psd网站建设有几块
  • 中端网站建设公司seo外贸网站
  • python在线免费网站c做项目的网站
  • 电影网站权重怎么做php旅游网站论文
  • 设计说明生成器长沙如何优化排名
  • 协会网站建设的优势学校网站建设管理
  • 网站详情页怎么做青岛做网站推广公司
  • 电商网站的支付模块怎么做如何开发一个微信公众号
  • 免费网站空间 asp.net二次开发焦点吧
  • 公益基金会网站开发的背景wordpress防黑
  • 网站seo运营wordpress媒体库地址修改
  • 挖掘关键词爱站网访问数据库的网站开发语言
  • 完整网站开发流程在线装修设计师咨询
  • 为什么网页不能打开建设银行网站软件开发生命周期
  • 网站开发商外包功能网站开发多少钱