首页系统综合问题Spring IOC容器接口设计

Spring IOC容器接口设计

时间2022-12-05 13:08:25发布分享专员分类系统综合问题浏览311

今天小编给各位分享capable的知识,文中也会对其通过Spring IOC容器接口设计和java编程,spring里ioc和aop用什么原理实现的等多篇文章进行知识讲解,如果文章内容对您有帮助,别忘了关注本站,现在进入正文!

内容导航:

  • Spring IOC容器接口设计
  • java编程,spring里ioc和aop用什么原理实现的
  • 快速切入:Spring框架核心概念总览
  • spring后置处理器接口有哪些
  • 一、Spring IOC容器接口设计

    Spring IoC容器的设计是分析Spring源码必不可少的一步。接口定义了各个组件之间的宏观关系,实现类则在实际层面上达成接口的功能。如果把整个IoC当做一个人体的话,接口就是骨骼,撑起了其整体架构,实现类是其血肉,使之丰满活动起来。

    下面就来看看IoC接口设计图

    IOC接口设计图

    第一条设计主线是:从接口BeanFactory到HierarchicalBeanFactory再到ConfigurableBeanFactory是一条设计路径。BeanFactory定义了IoC容器的最基础规范,包含了getBean(),containBean(),getType(),getAlias()等IoC容器的基本方法,而HierarchicalBeanFactory在继承了BeanFactory之后,添加了getParentBeanFactory方法,使BeanFactory具备了父容器管理功能,拥有了父子结构。而在接下来的ConfigurableBeanFactory主要定义了一些BeanFactory的配置功能,例如setParentBeanFactory()设置父容器,addBeanPostProcessor()配置Bean后置处理器,registerCustomEditor()配置自定义属性编辑器等。第二条设计主线是:以ApplicationContext应用上下文为核心的接口设计。从BeanFacotry到ListableBeanFactory再到ApplicationContext,再到ConfigurableApplicationContext。我们常用的应用上下文实例:ClassPathXmlApplicationContext,FileSystemXmlApplicationContext等都是ConfigurableApplicationContext的实现类。在ListabelBeanFactory接口中细化了BeanFactory的许多功能,例如:getBeanDefinitionNames获取工厂中定义的所有bean名称,containsBeanDefinition,getBeanDefinitionCount(),findAnnotationOnBean()等Bean解析方面的功能。另外ApplicationContext通过继承ApplicationEventPublisher拥有了发布应用上下文事件的能力,继承MessaegeSource拥有了处理国际化信息的能力,继承ResourceLoader可以以多种方式处理资源文件,继承LifeCycle拥有了生命周期管理的功能。 BeanFactory是IoC容器的基本规范,但它只拥有一些基本功能,空有骨骼,没有血肉,还无法应用于实际。ApplicationContext则在BeanFactory基础上赋予了更多实际中需要的高级特性。第三条设计主线是:BeanFactory到AutowireCapableBeanFactory再到ConfigurableListableBeanFactory接口。AutowireCapableBeanFactor这个接口很少在程序代码中使用,,它的功能主要是为了装配applicationContext管理之外的Bean。整合其他框架是这个接口的优势所在,它可以连接和填充那些生命周期不被Spring管理的已存在的bean实例。通过ApplicationContext的getAutowireCapableBeanFactory方法就很容易访问此接口.

    一、java编程,spring里ioc和aop用什么原理实现的

    控制反转(IOC)

    (理解好Ioc的关键是要明确“谁控制谁,控制什么,为何是反转(有反转就应该有正转了),哪些方面反转了”)
    1、Ioc—Inversion of Control:即“控制反转”,不是什么技术,而是一种设计思想。在Java开发中,Ioc意味着将你设计好的对象交给容器控制,而不是传统的在你的对象内部直接控制。
    2、谁控制谁,控制什么:传统Java SE程序设计,我们直接在对象内部通过new进行创建对象,是程序主动去创建依赖对象;而IoC是有专门一个容器来创建这些对象即由Ioc容器来控制对象的创建。
    谁控制谁?当然是IoC 容器控制了对象。
    控制什么?那就是主要控制了外部资源获取(不只是对象包括比如文件等)。
    3、为何是反转,哪些方面反转了: 有反转就有正转,传统应用程序是由我们自己在对象中主动控制去直接获取依赖对象,也就是正转;而反转则是由容器来帮忙创建及注入依赖对象。
    为何是反转?因为由容器帮我们查找及注入依赖对象,对象只是被动的接受依赖对象,所以是反转。
    哪些方面反转了?依赖对象的获取被反转了。
    还是不明白没事,下面搞个简单案例来说就懂啦 !!!
    例子:当我们在任何一个有实际开发意义的程序项目中,我们会使用很多类来描述他们特有的功能,并且通过类与类之间的相互协作来完成特定的业务逻辑。这个时候,每个类都需要负责管理与自己有交互的类的引用和依赖,代码将会变的异常难以维护和极高的高耦合。而IOC的出现正是用来解决这个问题,我们通过IOC将这些依赖对象的创建、协调工作交给spring容器去处理,每个对象值需要关注其自身的业务逻辑关系就可以了。在这样的角度上来看,获得依赖的对象的方式,进行了反转,变成了由spring容器控制对象如何获取外部资源(包括其他对象和文件资料等)。
    总的来说:IOC就是通过在Xml配置文件里依赖注入来解决代码问题。

    IOC的注入类型有几种?主要可以划分为三种:构造函数注入、属性注入和接口注入。Spring支持构造函数注入和属性注入

    面向切面(AOP)

    (面向切面编程,AOP其实只是OOP的补充而已,AOP基本上是通过代理机制实现的。)
    我们管切入到指定类指定方法的代码片段称为切面,而切入到哪些类、哪些方法则叫切入点。有了AOP,我们就可以把几个类共有的代码,抽取到一个切片中,等到需要时再切入对象中去,从而改变其原有的行为。
    我们都知道 Java 是 OOP-面向对象编程的,它有自己的优势,也有自己的不足。比如说:在我们开发中,都会有一条业务主线(即客户的需求)。而我们要做的就是实现这个主线上的需求。我们在实现这些功能的时候,经常要干一些额外的不可避免的事情,比如事务的管理,日志的记录等,就很繁杂且代码量增多,所以 Spring 提供了另一种角度来思考程序结构,也就是把这一些事情剥离出来,然后适时适地的把它们加入到我们的代码中,比如说 声明式事务管理的时候,我们在 service 层检测到save*、update*这些方法要被调用的时候,我们先进行开启事务什么的,这就是AOP,面向编程的思想。

    AOP的术语:
    1、通知(Advice):就是你想要的功能,也就是上面说的 安全,事物,日志等。你给先定义好把,然后在想用的地方用一下
    2、连接点(JoinPoint):这个更好解释了,就是spring允许你使用通知的地方,那可真就多了,基本每个方法的前,后(两者都有也行),或抛出异常时都可以是连接点,spring只支持方法连接点.其他如aspectJ还可以让你在构造器或属性注入时都行,不过那不是咱关注的,只要记住,和方法有关的前前后后(抛出异常),都是连接点。
    3、切入点(Pointcut):上面说的连接点的基础上,来定义切入点,你的一个类里,有15个方法,那就有几十个连接点了对把,但是你并不想在所有方法附近都使用通知(使用叫织入,以后再说),你只想让其中的几个,在调用这几个方法之前,之后或者抛出异常时干点什么,那么就用切点来定义这几个方法,让切点来筛选连接点,选中那几个你想要的方法。
    4、切面(Aspect):切面是通知和切入点的结合。现在发现了吧,没连接点什么事情,连接点就是为了让你好理解切点,搞出来的,明白这个概念就行了。通知说明了干什么和什么时候干(什么时候通过方法名中的before,after,around等就能知道),而切入点说明了在哪干(指定到底是哪个方法),这就是一个完整的切面定义。
    5、引入(introduction):允许我们向现有的类添加新方法属性。这不就是把切面(也就是新方法属性:通知定义的)用到目标类中吗
    6、目标(target):引入中所提到的目标类,也就是要被通知的对象,也就是真正的业务逻辑,他可以在毫不知情的情况下,被咱们织入切面。而自己专注于业务本身的逻辑。
    7、代理(proxy):怎么实现整套aop机制的,都是通过代理,这个一会给细说。
    8、织入(weaving):把切面应用到目标对象来创建新的代理对象的过程。有3种方式,spring采用的是运行时,为什么是运行时,后面解释。

    二、快速切入:Spring框架核心概念总览



    简而言之,Spring是企业级Java的开源开发框架。Spring框架的核心功能可用于开发任何java应用程序。Spring框架的核心模块如下:


    任何由 Spring IoC 容器初始化的普通 Java 类都称为 Spring Bean。我们使用 spring 应用程序上下文来获取 Spring Bean 实例。 Spring IoC Container 管理 Spring Bean 范围/作用域的生命周期并在 bean 中注入任何所需的依赖项。

    Spring bean的不同作用域:

    对于任何 Java 应用程序,都有两个不同的作用域,称为单例(Singleton)和原型(Prototype)

    主要有三种不同的作用域(或范围),即 请求(request)、会话(session)和全局会话(global-session) ,专门针对基于 Spring 的 Java Web 应用程序。

    Singleton 是任何 bean 的默认作用域。这意味着每个 IoC 容器将创建单个 bean 实例。因此,单例 bean 不是线程安全的。

    要设置 spring bean 的范围,我们可以在 标签中使用scope属性。 @scope 用于基于注释的 DI。


    Spring 容器是 Spring 框架的核心。容器将创建对象,把它们连接在一起,配置它们,并管理它们从创建到销毁的完整生命周期。 Spring 容器使用依赖注入 (DI) 来管理组成应用程序的组件。

    有两种不同类型的容器:

    BeanFactory 容器 :这是 Spring 容器的核心。 org.springframework.beans.factory.BeanFactory 是一个接口,充当 IoC 容器,它实例化、配置和管理许多 bean。应用示例如下:


    ApplicationContext 容器 :org.springframework.context.ApplicationContext 接口也充当 IoC 容器,但 ApplicationContext 接口建立在 BeanFactory 接口之上,以提供一些BeanFactory 额外的功能,例如与 Spring 的 AOP 的简单集成、消息资源处理(对于 I18N )、事件传播、Web 应用程序的应用层特定上下文(例如 WebApplicationContext)。所以使用 ApplicationContext 比使用 BeanFactory更好些。示例代码如下:

    对于基于注解的依赖注入,使用@Autowired 注解。标有@Component/@Service/@Repository 等的类可以注入到标有@Autowired 的属性中

    @Autowired 应用于:


    1)基于构造器和setter的区别


    2)context:annotation-config 和 context:component-scan 的区别

    3)@Component、@Controller、@Repository & @Service 注解的区别

    如果一个类用@Component/@Controller/@Service/@Repository 注解标记,那么Spring DI 容器可以在组件扫描机制期间识别该类。但是,对于服务层类使用@Service 是个好主意,并且@Controller 应该在spring mvc web 控制器中使用。 @Repository 用于将 DAO 导入 DI 容器。此外,任何未经检查的异常都将被转换为 Spring DataAccessException。

    4)ViewResolver 与 MultipartResolver

    ViewResolver 用于按名称解析视图。该接口由 InternalResourceViewResolver 实现 ;

    MultipartResolver 用于处理 web 应用程序中的文件上传。

    5)Spring MVC 中的验证

    org.springframework.validation.Validator 接口支持 spring MVC 验证。验证表单的一些实用方法是 ValidationUtils 类中的 rejectIfEmptyOrWhitespace() 和 rejectIfEmpty()。示例如下:

    Spring MVC 中验证表单的另一种方法是:

    HandlerInterceptor 接口充当 spring MVC 拦截器。它在服务请求之前和之后拦截。如果您实现了 HandlerInterceptor 接口,则 preHandle()、postHandle() 和 afterCompletion() 是要覆盖的方法。但是,为了避免覆盖,您可以使用 HandlerInterceptorAdapter 类。


    实现 ServletContextAware 和 ServletConfigAware 接口并覆盖以下方法:

    数据库事务是一组被视为关联工作单元的操作。事务的主要原则是提交所有操作或在失败的情况下回滚所有操作。在交易中提交数据时,我们需要确保交易协议/称为 ACID(原子性-一致性-隔离-持久性)的属性:

    全局事务 vs 本地事务:


    脏读、幻读和不可重复读:


    隔离与传播:

    在旧版本的 spring 和 hibernate 集成中,需要 HibernateDAOSupport 和 HibernateTemplate。但是,较新版本的 Spring 不建议使用这两个类(这里仅做了解)。

    通常我们从 HibernateDAOSupport 扩展我们的 DAO 类,并且 getHibernateTemplate() 方法将可用于Hibernate会话中的 CRUD 操作。由于这不是推荐的方法,所以我们在 DAO 中注入会话工厂(SessionFactory)。下面的代码片段会给你一些关于 HibernateDAOSupport 和 HibernateTemplate 的想法:

    DAO 是一种设计模式,以最大限度地减少应用程序和后端之间的耦合;

    ORM 处理如何将对象映射到对象关系数据库中,从而减少数据库和应用程序之间的耦合。

    如果您在没有 DAO 的情况下使用 ORM,那么您的应用程序将变得依赖于 ORM,因此很难从一个 ORM(例如Hibernate)移动到另一个 ORM(例如 NoSQL)。

    Spring DAO 是使用@Repository 注解实现的。 Spring 存储库扩展 JPARepository 并传递 JPA 实体及其主键。

    最后,关于Spring框架相关的概念就简要介绍到这里,希望这能给你进入并深入Spring技术栈一个简单入口,而不会被Spring技术生态所惊吓(Spring现在都成软件开发技术的全家桶了,啥都有)——日进一步,锲而不舍,终将大成!

    三、spring后置处理器接口有哪些

    Spring中bean工厂后置处理器(BeanFactoryPostProcessor)使用

    激情的狼王

    简书作者
    0.2882017-11-24 11:00打开App

    Spring中bean工厂后置处理器也就是BeanFactoryPostProcessor接口,是用来干什么的呢?我们都知道一个好的框架必备的特性至少得有开闭原则,可扩展性。
    在前面的文章里SpringIOC源码阅读—BeanDefinitionDocumentReader我们了解到Spring对bean定义的载入有很多种方式,读取的过程是可插拔的,不论何种形式,spring的IOC容器只要获得了bean定义信息,都可以正常工作。而我们熟知的配置读取方式就是XML文件,如果你希望,可以自己定制配置信息的读取过程,这就是Spring的特性体现之一。
    同样BeanFactoryPostProcessor也是Spring可扩展性的一个体现,我们读一下这个接口的源码

    public interface BeanFactoryPostProcessor {


    void postProcessBeanFactory(ConfigurableListableBeanFactory beanFactory) throws BeansException;

    }
    注释的意思是允许我们在工厂里所有的bean被加载进来后但是还没初始化前,对所有bean的属性进行修改也可以add属性值。
    下面通过实例看下效果

    beans.xml








    我们定义一个普通bean和一个BeanFactroy后置处理器

    User类

    package xz.quartz.analysis;

    public class User {

    String name;
    String age;

    public User() {
    System.out.println("construtor");
    System.out.println("name:"+name+",age:"+age);
    }

    public void go(){
    System.out.println("age:"+age);
    }
    public String getName() {
    return name;
    }
    public void setName(String name) {
    this.name = name;
    }
    public String getAge() {
    return age;
    }
    public void setAge(String age) {
    this.age = age;
    }
    }

    BeanFactroy后置处理器类

    package xz.quartz.analysis;

    import org.springframework.beans.BeansException;
    import org.springframework.beans.MutablePropertyValues;
    import org.springframework.beans.factory.config.BeanDefinition;
    import org.springframework.beans.factory.config.BeanFactoryPostProcessor;
    import org.springframework.beans.factory.config.ConfigurableListableBeanFactory;

    public class beanfactorypostpro implements BeanFactoryPostProcessor{

    @Override
    public void postProcessBeanFactory(ConfigurableListableBeanFactory beanFactory) throws BeansException {
    System.out.println("******调用BeanFactoryPostProcessor开始");
    //获取到Spring中所有的beanName
    String[] beanStr = beanFactory.getBeanDefinitionNames();
    //循环bean做出自定义的操作
    for (String beanName : beanStr) {
    System.out.println("bean name:"+beanName);
    if ("user".equals(beanName)) {
    BeanDefinition beanDefinition = beanFactory.getBeanDefinition(beanName);
    System.out.println("修改user的age值");
    beanDefinition.getPropertyValues().add("age", "20");
    }
    }
    System.out.println("******调用BeanFactoryPostProcessor结束");
    }
    }
    在上面BeanFactoryPostProcessor的实现类里通过我写的注释可以看到这个工厂后置器获取到所有的beanName,并且可以对特定的bean或者全部bean进行操作,这也就是后置器的核心所在之处。

    main方法

    public static void main(String[] args) {
    ApplicationContext applicationContext = new ClassPathXmlApplicationContext("classpath:beans.xml");
    System.out.println("获取到User实例 ");
    ((User)applicationContext.getBean("user")).go();
    }
    主函数中第一行初始化的时候,读取beans.xml时,会获取实现了BeanFactoryPostProcessor接口的bean,然后把它作为后置处理器类来处理。
    然后我们通过调用user的go方法,输出age的值来看下

    ******调用BeanFactoryPostProcessor开始
    bean name:user
    修改user的age值
    bean name:beanfactorypostpro
    ******调用BeanFactoryPostProcessor结束
    construtor
    name:null,age:null
    获取到User实例
    age:20
    我们在BeanFactroy后置处理器类里给user的age属性成功赋值成20,大家通过程序实例可以看到后置处理器的作用和用法了。

    在这里提出两个疑问

    1.后置处理器和bean指定的init-method还有构造方法的顺序是谁先谁后呢?
    2.这三个方法同时对属性赋值,最终会是哪个起作用呢?

    对上面的两个问题,我们改造下代码,先把构造方法加上赋值过程

    User类

    package xz.quartz.analysis;

    public class User {
    String name;
    String age;

    void init(){
    System.out.println("init");
    }

    public User() {
    System.out.println("construtor");
    name = "zx-construtor";
    age = "zx-construtor";
    System.out.println("name:"+name+",age:"+age);
    }

    public void go(){
    System.out.println("最终age的值:"+age);
    }
    public String getName() {
    return name;
    }
    public void setName(String name) {
    this.name = name;
    }
    public String getAge() {
    return age;
    }
    public void setAge(String age) {
    this.age = age;
    }
    }

    输出结果:

    ******调用BeanFactoryPostProcessor开始
    bean name:user
    修改user的age值
    bean name:beanfactorypostpro
    ******调用BeanFactoryPostProcessor结束
    construtor
    name:zx-construtor,age:zx-construtor
    init
    name:zx-construtor,age:20
    获取到User实例
    最终age的值:20
    可以看到程序先执行后置器将值改为20,然后执行的构造方法,改为zx-construtor,但是最终age的值为20,到好文

    关于capable的问题,通过《快速切入:Spring框架核心概念总览》、《spring后置处理器接口有哪些》等文章的解答希望已经帮助到您了!如您想了解更多关于capable的相关信息,请到本站进行查找!

    爱资源吧版权声明:以上文中内容来自网络,如有侵权请联系删除,谢谢。

    capable
    word转化pdf怎么做 word转化pdf软件介绍 莱盟集团旗下Helio荣获Frostamp;Sullivan颁发“北美肝癌早筛年度最佳实践公司”