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

wp网站建设模板wordpress添加作者信息

wp网站建设模板,wordpress添加作者信息,响应式网站开发哪个好,网站建设咨询什么目录 一. 前言 二. IoC 基础 2.1. IoC 是什么 2.2. IoC 能做什么 2.3. IoC 和 DI 是什么关系 三. IoC 配置的三种方式 3.1. XML 配置 3.2. Java 配置 3.3. 注解配置 四. 依赖注入的三种方式 4.1. 属性注入#xff08;setter 注入#xff09; 4.2. 构造方法注入setter 注入 4.2. 构造方法注入Construct 注入 4.3. 注解注入 五. IoC 和 DI 使用问题总结 5.1. 为什么推荐构造器注入方式 5.2. 在使用构造器注入方式时注入了太多的类导致 Bad Smell 怎么办 5.3. Autowired、Resource、Inject 等注解注入有何区别 5.3.1. Autowired 注解 5.3.2. Resource 注解 5.3.3. Inject 注解 5.4. 小结 一. 前言 IoCInversion of Control即控制反转不是什么技术而是一种设计思想。在 Java 开发中IoC 意味着将你设计好的对象交给容器控制而不是传统的在你的对象内部直接控制。IoC Container 管理的是 Spring Bean 那么 Spring Bean 是什么呢Spring 里面的 Bean 就类似于定义的一个组件而这个组件的作用就是实现某个功能的这里所定义的 Bean 就相当于给了你一个更为简便的方法来调用这个组件去实现你要完成的功能。 如果你有精力看英文首推 Martin Fowler 大师的 《Inversion of Control Containers and the Dependency Injection pattern》其次 IoC 作为一种设计思想不要过度解读而是应该简化理解。 在《通过一个 Spring 的 HelloWorld 引入 Spring 要点》中向你展示了 IoC 的基础含义同时以此发散了一些 IoC 相关知识点本节将在此基础上进一步解读 IoC 的含义以及 IoC 的使用方式。 二. IoC 基础 2.1. IoC 是什么 IoCInversion of Control即控制反转不是什么技术而是一种设计思想。在 Java 开发中IoC 意味着将你设计好的对象交给容器控制而不是传统的在你的对象内部直接控制。 我们来深入分析一下 1. 谁控制谁控制什么 传统 Java SE 程序设计我们直接在对象内部通过 new 进行创建对象是程序主动去创建依赖对象而 IoC 是有专门一个容器来创建这些对象即由 IoC 容器来控制对象的创建谁控制谁当然是 IoC 容器控制了对象控制什么那就是主要控制了外部资源获取不只是对象包括比如文件等。 2. 为何是反转哪些方面反转了 有反转就有正转传统应用程序是由我们自己在对象中主动控制去直接获取依赖对象也就是正转而反转则是由容器来帮忙创建及注入依赖对象为何是反转因为由容器帮我们查找及注入依赖对象对象只是被动的接受依赖对象所以是反转哪些方面反转了依赖对象的获取被反转了。 图例说明 传统程序设计下都是主动去创建相关对象然后再组合起来 当有了 IoC/DI 的容器后在客户端类中不再主动去创建这些对象了如图 2.2. IoC 能做什么 IoC 不是一种技术只是一种思想一个重要的面向对象编程的法则它能指导我们如何设计出松耦合、更优良的程序。 传统应用程序都是由我们在类内部主动创建依赖对象从而导致类与类之间高耦合难于测试。有了 IoC 容器后把创建和查找依赖对象的控制权交给了容器由容器进行注入组合对象所以对象与对象之间是松散耦合这样也方便测试利于功能复用更重要的是使得程序的整个体系结构变得非常灵活。 其实 IoC 对编程带来的最大改变不是从代码上而是从思想上发生了主从换位的变化。应用程序原本是老大要获取什么资源都是主动出击但是在 IoC/DI 思想中应用程序就变成被动的了被动的等待 IoC 容器来创建并注入它所需要的资源了。 IoC 很好的体现了面向对象设计法则之一 —— 好莱坞法则“别找我们我们找你”即由 IoC 容器帮对象找相应的依赖对象并注入而不是由对象主动去找。关于好莱坞法则可参见《面向对象的五大基本原则SOLID及扩展原则》。 2.3. IoC 和 DI 是什么关系 控制反转IoC是通过依赖注入实现的其实它们是同一个概念的不同角度描述。通俗来说就是 IoC 是设计思想DI 是实现方式。 DIDependency Injection即依赖注入组件之间依赖关系由容器在运行期决定形象地说即由容器动态的将某个依赖关系注入到组件之中。依赖注入的目的并非为软件系统带来更多功能而是为了提升组件重用的频率并为系统搭建一个灵活、可扩展的平台。通过依赖注入机制我们只需要通过简单的配置而无需任何代码就可指定目标需要的资源完成自身的业务逻辑而不需要关心具体的资源来自何处由谁实现。 我们来深入分析一下 1. 谁依赖于谁 当然是应用程序依赖于 IoC 容器。 2. 为什么需要依赖 应用程序需要 IoC 容器来提供对象需要的外部资源。 3. 谁注入谁 很明显是 IoC 容器注入应用程序某个对象应用程序依赖的对象。 4. 注入了什么 就是注入某个对象所需要的外部资源包括对象、资源、常量数据。 5. IoC 和 DI 有什么关系呢 其实它们是同一个概念的不同角度描述由于控制反转概念比较含糊可能只是理解为容器控制对象这一个层面很难让人想到谁来维护对象关系所以2004年大师级人物 Martin Fowler 又给出了一个新的名字依赖注入。相对 IoC  而言依赖注入明确描述了被注入对象依赖 IoC 容器配置依赖对象。通俗来说就是 IoC 是设计思想DI 是实现方式。 三. IoC 配置的三种方式 在《通过一个 Spring 的 HelloWorld 引入 Spring 要点》已经给出了三种配置方式这里再总结下总体上目前的主流方式是 注解 Java 配置。 3.1. XML 配置 顾名思义就是将 Bean 的信息配置在 xml 文件里通过 Spring 加载文件为我们创建 Bean。这种方式出现在很多早前的 SSM 项目中将第三方类库或者一些配置工具类都以这种方式进行配置主要原因是由于第三方类不支持 Spring 注解。 优点 可以使用于任何场景结构清晰通俗易懂。缺点 配置繁琐不易维护枯燥无味扩展性差。 举例 配置 xx.xml 文件声明命名空间和配置 Bean ?xml version1.0 encodingUTF-8? beans xmlnshttp://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.xsd!-- services --bean iduserService classcom.lm.it.springframework.service.UserServiceImplproperty nameuserDao refuserDao/!-- additional collaborators and configuration for this bean go here --/bean!-- more bean definitions for services go here -- /beans 3.2. Java 配置 将类的创建交给我们配置的 JavaConfig 类来完成Spring 只负责维护和管理采用纯 Java 创建方式。其本质上就是把在 XML 上的配置声明转移到 Java 配置类中。 优点适用于任何场景配置方便因为是纯 Java 代码扩展性高十分灵活。缺点由于是采用 Java 类的方式声明不明显如果大量配置可读性比较差。 举例 1. 创建一个配置类 添加 Configuration 注解声明为配置类。 2. 创建方法方法上加上 Bean该方法用于创建实例并返回该实例创建后会交给 Spring 管理方法名建议与实例名相同首字母小写。注实例类不需要加任何注解 /*** BeansConfig*/ Configuration public class BeansConfig {/*** return user dao*/Bean(userDao)public UserDaoImpl userDao() {return new UserDaoImpl();}/*** return user service*/Bean(userService)public UserServiceImpl userService() {UserServiceImpl userService new UserServiceImpl();userService.setUserDao(userDao());return userService;} } 3.3. 注解配置 通过在类上加注解的方式来声明一个类交给 Spring 管理Spring 会自动扫描带有Component、Controller、Service、Repository 这四个注解的类然后帮我们创建并管理前提是需要先配置 Spring 的注解扫描器。 优点开发便捷通俗易懂方便维护。缺点具有局限性对于一些第三方资源无法添加注解。只能采用 XML 或 JavaConfig 的方式配置。 举例 1. 对类添加 Component 相关的注解比如Controller、Service、Repository。 2. 设置 ComponentScan 的 basePackage比如 context:component-scan base-packagecom.lm.it.springframework 或者 ComponentScan(com.lm.it.springframework) 注解或者 new AnnotationConfigApplicationContext(com.lm.it.springframework) 指定扫描的basePackage /*** UserService*/ Service public class UserServiceImpl {/*** user dao impl.*/Autowiredprivate UserDaoImpl userDao;/*** find user list.** return user list*/public ListUser findUserList() {return userDao.findUserList();} } 四. 依赖注入的三种方式 常用的注入方式主要有三种属性注入setter 注入、构造方法注入Construct 注入、基于注解的注入接口注入。 4.1. 属性注入setter 注入 在 XML 配置方式中property 都是 setter 方式注入比如下面的 xml ?xml version1.0 encodingUTF-8? beans xmlnshttp://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.xsd!-- services --bean iduserService classcom.lm.it.springframework.service.UserServiceImplproperty nameuserDao refuserDao/!-- additional collaborators and configuration for this bean go here --/bean!-- more bean definitions for services go here -- /beans 本质上包含两步 第一步需要 new UserServiceImpl() 创建对象所以需要默认构造函数。第二步调用 setUserDao() 函数注入 userDao 的值所以需要 setUserDao() 函数。   所以对应的 Service 类是这样的 /*** UserService*/ public class UserServiceImpl {/*** user dao impl.*/private UserDaoImpl userDao;/*** init.*/public UserServiceImpl() {}/*** find user list.** return user list*/public ListUser findUserList() {return this.userDao.findUserList();}/*** set dao.** param userDao user dao*/public void setUserDao(UserDaoImpl userDao) {this.userDao userDao;} } 在 Java 配置和注解方式下 /*** UserService*/ public class UserServiceImpl {/*** user dao impl.*/private UserDaoImpl userDao;/*** find user list.** return user list*/public ListUser findUserList() {return this.userDao.findUserList();}/*** set dao.** param userDao user dao*/Autowiredpublic void setUserDao(UserDaoImpl userDao) {this.userDao userDao;} } 在 Spring3.x 刚推出的时候推荐使用注入的就是这种但是这种方式比较麻烦所以在 Spring4.x 版本中推荐构造函数注入。 4.2. 构造方法注入Construct 注入 在 XML 配置方式中constructor-arg 是通过构造函数参数注入比如下面的 xml ?xml version1.0 encodingUTF-8? beans xmlnshttp://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.xsd!-- services --bean iduserService classcom.lm.it.springframework.service.UserServiceImplconstructor-arg nameuserDao refuserDao/!-- additional collaborators and configuration for this bean go here --/bean!-- more bean definitions for services go here -- /beans 本质上是 new UserServiceImpl(userDao) 创建对象, 所以对应的 Service 类是这样的 /*** UserService*/ public class UserServiceImpl {/*** user dao impl.*/private final UserDaoImpl userDao;/*** init.* param userDaoImpl user dao impl*/public UserServiceImpl(UserDaoImpl userDaoImpl) {this.userDao userDaoImpl;}/*** find user list.** return user list*/public ListUser findUserList() {return this.userDao.findUserList();} } 在 Java 配置和注解方式下 /*** UserService*/Service public class UserServiceImpl {/*** user dao impl.*/private final UserDaoImpl userDao;/*** init.* param userDaoImpl user dao impl*/Autowired // 这里Autowired也可以省略public UserServiceImpl(final UserDaoImpl userDaoImpl) {this.userDao userDaoImpl;}/*** find user list.** return user list*/public ListUser findUserList() {return this.userDao.findUserList();} } 在 Spring4.x 版本中推荐的注入方式就是这种。 4.3. 注解注入 以 Autowired自动注入注解注入为例修饰符有三个属性byType、byName、Constructor。默认按照 byType 注入。 byType查找所有的 set 方法将符合参数类型的 Bean 注入。byName被注入 Bean 的 id 名必须与 set 方法后半截匹配并且 id 名称的第一个单词首字母必须小写这一点与手动 set 注入有点不同。constructor通过构造方法进行自动注入Spring 会匹配与构造方法参数类型一致的 Bean进行注入如果有一个多参数的构造方法一个只有一个参数的构造方法在容器中查找到多个匹配多参数构造方法的 Bean那么 Spring 会优先将 Bean 注入到多参数的构造方法中。 示例 /*** UserService*/ Service public class UserServiceImpl {/*** user dao impl.*/Autowiredprivate UserDaoImpl userDao;/*** find user list.** return user list*/public ListUser findUserList() {return userDao.findUserList();} } 五. IoC 和 DI 使用问题总结 5.1. 为什么推荐构造器注入方式 先来看看 Spring 在文档里怎么说 The Spring team generally advocates constructor injection as it enables one to implement application components as immutable objects and to ensure that required dependencies are not null. Furthermore constructor-injected components are always returned to client (calling) code in a fully initialized state. 简单的翻译一下这个构造器注入的方式能够保证注入的组件不可变并且确保需要的依赖不为空。此外构造器注入的依赖总是能够在返回客户端组件代码的时候保证完全初始化的状态。 下面来简单的解释一下 依赖不可变其实说的就是 final 关键字。依赖不为空省去了我们对其检查当要实例化 UserServiceImpl 的时候由于自己实现了有参数的构造函数所以不会调用默认构造函数那么就需要 Spring 容器传入所需要的参数所以就两种情况1. 有该类型的参数 -- 传入OK 2. 无该类型的参数 -- 报错。完全初始化的状态这个可以跟上面的依赖不为空结合起来向构造器传参之前要确保注入的内容不为空那么肯定要调用依赖组件的构造方法完成实例化。而在 Java 类加载实例化的过程中构造方法是最后一步之前如果有父类先初始化父类然后自己的成员变量最后才是构造方法所以返回来的都是初始化之后的状态。 所以通常是这样的 /*** UserService*/Service public class UserServiceImpl {/*** user dao impl.*/private final UserDaoImpl userDao;/*** init.* param userDaoImpl user dao impl*/public UserServiceImpl(final UserDaoImpl userDaoImpl) {this.userDao userDaoImpl;} } 如果使用 setter 注入缺点显而易见对于 IoC 容器以外的环境除了使用反射来提供它需要的依赖之外无法复用该实现类。而且将一直是个潜在的隐患因为你不调用将一直无法发现 NPE 的存在。 // 这里只是模拟一下正常来说我们只会暴露接口给客户端不会暴露实现。 UserServiceImpl userService new UserServiceImpl(); userService.findUserList(); // - NullPointerException, 潜在的隐患 循环依赖的问题使用 field 注入可能会导致循环依赖即 A 里面注入 BB 里面又注入 A public class A {Autowiredprivate B b; }public class B {Autowiredprivate A a; } 如果使用构造器注入在 Spring 项目启动的时候就会抛出BeanCurrentlyInCreationExceptionRequested bean is currently in creation: Is there an unresolvable circular reference从而提醒你避免循环依赖如果是 field 注入的话启动的时候不会报错在使用那个 Bean 的时候才会报错。 5.2. 在使用构造器注入方式时注入了太多的类导致 Bad Smell 怎么办 比如当你一个 Controller 中注入了太多的 Service 类Sonar 会给你提示相关告警 对于这个问题说明你的类当中有太多的责任那么你要好好想一想是不是自己违反了类的单一性职责原则从而导致有这么多的依赖要注入。 5.3. Autowired、Resource、Inject 等注解注入有何区别 5.3.1. Autowired 注解 在 Spring 2.5 引入了 Autowired 注解 Target({ElementType.CONSTRUCTOR, ElementType.METHOD, ElementType.PARAMETER, ElementType.FIELD, ElementType.ANNOTATION_TYPE}) Retention(RetentionPolicy.RUNTIME) Documented public interface Autowired {boolean required() default true; } 从 Autowired 注解源码上看可以使用在下面这些地方 Target(ElementType.CONSTRUCTOR) #构造函数 Target(ElementType.METHOD) #方法 Target(ElementType.PARAMETER) #方法参数 Target(ElementType.FIELD) #字段、枚举的常量 Target(ElementType.ANNOTATION_TYPE) #注解 还有一个 required 属性默认是 true。 总结 Autowired 是 Spring 自带的注解通过 AutowiredAnnotationBeanPostProcessor 类实现的依赖注入Autowired 可以作用在 CONSTRUCTOR、METHOD、PARAMETER、FIELD、ANNOTATION_TYPEAutowired 默认是根据类型byType 进行自动装配的如果有多个类型一样的 Bean 候选者需要指定按照名称byName 进行装配则需要配合 Qualifier。 指定名称后如果 Spring IoC 容器中没有对应的组件Bean 抛出NoSuchBeanDefinitionException。也可以将 Autowired 中 required 配置为 false如果配置为false 之后当没有找到相应 Bean 的时候系统不会抛异常。 代码示例 在字段属性上 Autowired private HelloDao helloDao; 或者 private HelloDao helloDao;public HelloDao getHelloDao() {return helloDao; }Autowired public void setHelloDao(HelloDao helloDao) {this.helloDao helloDao; } 或者 private HelloDao helloDao;// Autowired public HelloServiceImpl(Autowired HelloDao helloDao) {this.helloDao helloDao; } // 构造器注入也可不写Autowired也可以注入成功。 将 Autowired 写在被注入的成员变量上setter 或者构造器上就不用在 xml 文件中配置了。 如果有多个类型一样的 Bean 候选者则默认根据设定的属性名称进行获取。如 HelloDao 在Spring 中有 helloWorldDao 和 helloDao 两个 Bean 候选者。 Autowired private HelloDao helloDao; 首先根据类型获取发现多个 HelloDao然后根据 helloDao 进行获取如果要获取限定的其中一个候选者结合 Qualifier 进行注入。 Autowired Qualifier(helloWorldDao) private HelloDao helloDao; 注入名称为 helloWorldDao 的 Bean组件。Qualifier(XXX) 中的 XX 是 Bean 的名称所以 Autowired 和 Qualifier 结合使用时自动注入的策略就从 byType 转变成 byName 了。 多个类型一样的 Bean 候选者也可以 Primary 进行使用设置首选的组件也就是默认优先使用哪一个。 注意使用 Qualifier 时候如果设置的指定名称的 Bean 不存在则会抛出异常如果防止抛出异常可以使用 Qualifier(xxxxyyyy) Autowired(required false) private HelloDao helloDao; 在 SpringBoot 中也可以使用 BeanAutowired 进行组件注入将 Autowired 加到参数上其实也可以省略。 Bean public Person getPerson(Autowired Car car) {return new Person(); } // Autowired 其实也可以省略 5.3.2. Resource 注解 Resource 注解源码 Target({TYPE, FIELD, METHOD}) Retention(RUNTIME) public interface Resource {String name() default ;// 其他省略 } 从 Resource 注解源码上看可以使用在下面这些地方 Target(ElementType.TYPE) #接口、类、枚举、注解 Target(ElementType.FIELD) #字段、枚举的常量 Target(ElementType.METHOD) #方法 name 指定注入指定名称的组件。 总结 Resource 是 JSR250 规范的实现在 javax.annotation 包下Resource 可以作用 TYPE、FIELD、METHOD 上Resource 是默认根据属性名称进行自动装配的如果有多个类型一样的 Bean 候选者则可以通过 name 进行指定进行注入。 代码示例 Component public class SuperMan {Resourceprivate Car car; } 按照属性名称 car 注入容器中的组件。如果容器中除了 BMW 还有 BYD 两种类型组件。指定加入 BMW。如下代码 Component public class SuperMan {Resource(name BMW)private Car car; } name 的作用类似 Qualifier。 5.3.3. Inject 注解 Inject 注解源码 Target({ METHOD, CONSTRUCTOR, FIELD }) Retention(RUNTIME) Documented public interface Inject {} 从 Inject 注解源码上看可以使用在下面这些地方 Target(ElementType.CONSTRUCTOR) #构造函数 Target(ElementType.METHOD) #方法 Target(ElementType.FIELD) #字段、枚举的常量 总结 Inject 是 JSR330Dependency Injection for Java中的规范需要导入 javax.inject.Inject jar 包 才能实现注入Inject 可以作用 CONSTRUCTOR、METHOD、FIELD 上Inject 是根据类型进行自动装配的如果需要按名称进行装配则需要配合 Named。 代码示例 Inject private Car car; 指定加入 BMW 组件 Inject Named(BMW) private Car car; Named 的作用类似 Qualifier。 5.4. 小结 1. Autowired 是 Spring 自带的Resource 是 JSR250 规范实现的Inject 是 JSR330 规范实现的。 2. Autowired、Inject 用法基本一样不同的是 Inject 没有 required 属性。 3. Autowired、Inject 是默认按照类型匹配的Resource 是按照名称匹配的。 4. Autowired 如果需要按照名称匹配需要和 Qualifier 一起使用Inject 和 Named 一起使用Resource 则通过 name 进行指定。
http://www.zqtcl.cn/news/943545/

相关文章:

  • 福建省建设人才与科技发展中心网站首页关于制作网站收费标准
  • 什么软件可以发帖子做推广中山优化网站
  • 中山网站建设开发网络营销的基本功能
  • 温州平阳县网站建设兼职免费下载简历模板
  • 导购网站 转化率wordpress 拓展
  • 美文分享网站源码互联网网站建设
  • 做网站用php还是python建设网站价格
  • 平台网站怎么做诱导网站怎么做
  • 网站建设人员构成网址申请域名
  • 微网站建设找哪家公司好郑州一凡网站建设
  • 江阴网站制作公司泉州网站建设论坛
  • 最新章节 62.一起来做网站吧时钟插件+wordpress
  • 惠州市建设规划局网站网页设计实训报告word
  • 大众汽车网站建设鳌江网站建设
  • 佛山外贸网站建设公司网站与网页区别
  • HTML网站建设课程微商怎么做网站
  • 专业数据分析网站wordpress 很差
  • 请人做个网站多少钱google推广妙招
  • 郑州销售网站开一个设计公司
  • 建筑公司网站常用长尾词网页设计实训总结100字
  • 网站开发项目业务要求wordpress前台注册登陆
  • 上海人才网官网招聘人力资源专业wordpress seo title
  • 简单html网站网页设计培训学费多少
  • 麻城网站建设投标网招标网
  • 网站建设行业细分专业动漫如何制作
  • 做地方网站数据哪里来模板网站建设教程视频
  • 株洲建设网站制作网络怎么推广自己的产品
  • dtu网站开发赣县网站制作
  • 东莞旅游网站建设微网站怎么做
  • 网站怎么没有排名做义工旅行有哪些网站