有多少种方法可以配置Spring框架? 技术上它们之间有什么区别? (不是利弊……)

我正在研究这本书(我强烈推荐),我很困惑作者如何解释Spring框架的配置方式。

您可以在此处查看本书中使用的一些代码示例。 (任何人都可以使用它们。)如果您想查看,我所指的代码将是第2章的代码。

无论如何,本书指出有三种配置Spring容器的方法


基于XML的配置

这将需要一个类似于下面的xml文件:

        

然后为了引导Spring,将使用的代码是:

 ClassPathXmlApplicationContext applicationContext = new ClassPathXmlApplicationContext("/com/wiley/beginningspring/ch2/ch2-beans.xml"); 

我此刻没有任何困惑。


基于Java的配置

在此Configuration方法中,将有一个配置类,如下所示:

 @Configuration public class Ch2BeanConfiguration { @Bean public AccountService accountService() { AccountServiceImpl bean = new AccountServiceImpl(); bean.setAccountDao(accountDao()); return bean; } @Bean public AccountDao accountDao() { AccountDaoInMemoryImpl bean = new AccountDaoInMemoryImpl(); return bean; } } 

并且负责引导Spring的代码如下所示:

 ApplicationContext applicationContext = new AnnotationConfigApplicationContext(Ch2BeanConfiguration.class); 

所以到了这里,对我来说一切都很清楚。 (有点……)我还要注意,这里我们实际上有一个名为@Configuration的Annotation …


基于注释的配置

书中解释的最后一种配置方法是基于注释的配置

有一个xml文件,就像我们在基于XML的配置中一样,但是要小得多:

     

所有bean都有注释,例如:

 @Component, @Service 

等等..

并且所有依赖项都有注释:

 @Autowired 

这样可以注入豆类。

Spring框架在此配置方法中引导的方式如下:

 ClassPathXmlApplicationContext applicationContext = new ClassPathXmlApplicationContext("/ch2-beans.xml"); 

这是我的问题:

为什么(所谓的) 基于注释的配置实际上使用的是ClassPathXmlApplicationContext而不是AnnotationConfigApplicationContext ? 后者似乎更适合在配置中使用,其中包含“基于注释”的字样,不是吗?

书中解释的基于Java的配置似乎应该称为基于注释的配置

在本书中解释的基于注释的配置实际上似乎是这样的:基于XML的配置与Autowired bean。 它甚至没有@Configuration注释,“基于Java的配置”具有…

有多少种方法可以配置Spring框架?

为避免混淆,我们应该理解, 配置定义bean定义两回事 。 定义配置有三种方法,默认情况下在Spring 4中可用:

  • 基于xml的配置,在xml文件中描述配置时;
  • 基于java的配置,当配置为Java类时,标记有特定的注释;
  • 基于groovy的配置,当配置是带有Groovy代码的文件时;

有两种方法可以将bean定义添加到应用程序中:

  • bean定义中配置 ,当您通过配置中的声明手动添加bean时。

    在这种情况下,定义将基于配置类型。 对于xml-config,它将是标记,对于基于java的配置 – 带有@Bean注释的方法和用于Groovy的beans {...}构造。

  • 基于注释的 bean定义,当您使用特定注释标记bean类时(如@Component@Service @Controller@Service @Controller等)。 这种类型的配置使用类路径扫描 。

    在这种情况下,您必须指定扫描类路径的指令。 对于xml-config,它将是 ,用于java-config – @ComponentScan注释,用于Groovy ctx.'component-scan'(...)调用。

如您所见,您可以使用不同组合的配置和bean定义。

请注意,如果使用基于xml的配置,则可以选择驱动依赖项注入的方法:手动在xml中,或使用注释(@ @Autowire@Required等)。 在最后的情况下,您必须定义 。 但是不要混淆bean定义和dependency injection控制。

现在基于这个观点,我们可以尝试回答你的问题:

为什么(所谓的)基于注释的配置实际上使用的是ClassPathXmlApplicationContext而不是AnnotationConfigApplicationContext?

本书的作者混淆了概念。 实际上,这是一个基于xml的配置,带有基于注释的bean定义。

书中解释的基于Java的配置似乎应该称为基于注释的配置。

你是对的 – 基于Java的配置确实主动使用注释,可以称为基于注释。 但注释是Java的一部分。 此外,这是一个传统术语, 在文档中指定 。

有多少种方法可以配置Spring框架?

因此,默认情况下,我们有三种方式来描述配置,以及两种定义bean的方法。 这有六种方式来配置Spring框架(默认情况下)。 但是,当然,所有这些方式都可以相互结合使用。

理解这一点的最简单方法是研究框架的长期历史。

  • 基于XML的配置 – 从头开始​​ – 版本1 – 请参阅ClassPathXmlApplicationContext的javadoc 。 这是在2004年3月左右,J2EE 1.4的时候,它有巨大的xml配置,Spring是大简化(XML也是,但更简单)。 这会将XML用于所有内容,包括指定自动assembly或直接依赖于哪些依赖项(您的ref =“accoundDao”示例)。

  • 基于注释的配置 – 在Spring 2.5中 – 这是对Java EE 5的反应,引入了像@Autowired这样的新语言,在XML文件中仍然存在一些上下文配置 – 通常你会定义要扫描哪些包以及其余部分是基于注释自动完成的 – 因此得名。

  • Spring 3中提供了基于Java的配置,在以后的版本中进行了改进。 这是在引入AnnotationConfigApplicationContext和Configuration注释时 – 您可能完全删除XML – >基于java的配置。 虽然这只是后来版本4+才变得实用,因为aop,jdbc等有大量的xml帮助器标签。

除了这3个(实际上2个和2个使用相同的ApplicationContext类)之外,还有其他创建上下文的方法:

  • 看看ApplicationContext接口的所有实现类
  • 用于junit测试的SpringJUnit4ClassRunner
  • 我打赌还有其他我不知道的方法

不完全是。 配置Spring框架只有两种方法。 Spring框架的两个基本配置工具是:

  • XML文件(java文件外)
  • 基于Java(5 +)的注释(在java文件中)

它们都可以用于:

  • 配置应用程序上下文(意味着添加bean) – 具体应用程序上下文的构造函数接受xml文件,要扫描的包或直接命名的类以加载
  • 在Web应用程序的情况下引导应用程序上下文 – 使用web.xml与使用实现WebApplicationInitializer的类

最后但并非最不重要:

  • 您可以使用从xml配置文件中扫描注释
  • 您可以使用@import从带注释的配置Bean加载xml文件

您书中第二种称为基于Java的配置 ,是一种特殊的注释@Configuration 。 用它注释的类通常是应用程序上下文中的bean,但它也可以在一个方法上声明带有@Bean注释的其他bean。 这就是为什么这些类通常直接加载而不是扫描bean的原因。

第三种方法称为基于注释的配置 ,它只是两种模式的混合,您可以在更高级别使用xml配置,只需扫描其他bean的包。


TL / DR:在spring框架中只有两种方法来配置应用程序上下文:

  • xml配置文件
  • java注释

他们可以混在一起

但是每个bean都可以用3种方式声明:

  • 来自xml文件
  • @Configuration注释bean中使用@Bean注释
  • 直接使用@Component (或任何专门的注释@Controller@Service @Controller等)

现在为您提出准确的问题:

为什么(所谓的)基于注释的配置实际上使用的是ClassPathXmlApplicationContext而不是AnnotationConfigApplicationContext?

因为ApplicationContext首先从xml配置文件初始化。 稍后在标签的帮助下进行包扫描。 如果直接从配置类或通过包扫描初始化它,则使用AnnotationConfigApplicationContext

书中解释的基于Java的配置似乎应该称为基于注释的配置。

他们称之为Java Based,因为它不需要xml,因此配置只使用Java

首先,我想感谢肯贝科夫提供的更有说服力的答案。 我试图即兴发表他的回答,这样任何人都可以在这方面了解更多。

配置定义:

Spring 4包含3种定义其配置的方法。 他们是

在此处输入图像描述

注释的优点:

  1. 所有information is in a single file (无需打开两个文件来配置给定的行为)

  2. 当类更改时, no need to modify the xml file

  3. 在重新分解应用程序代码时,Annoations通常被认为更直观,更健壮。 他们也受益于像guise提供的更好的IDE指导。 但他们将应用程序代码与DI问题混在一起 应用程序依赖于框架。 清除分离几乎是不可能的。 Annotations are also limited when describing different injection behaviour at the same place (constructor, field) dependent on other circumstances (eg robot legs problem). 此外,它们不允许像处理自己的源一样处理外部类(库代码)。 因此,它们被认为比XML运行得更快。

xml文件的优点:

  1. POJO与其行为之间的明确分离

  2. 当您不知道哪个POJO负责该行为时,更容易找到POJO(搜索文件的子集而不是所有源代码)

  3. XML具有声明式样式的唯一优点,它与应用程序代码本身明确分开。 这与DI问题无关。 缺点是verbositypoor re-factoring robustness poor re-factoringa general runtime failure行为。 与IDE支持例如Java相比,只有一般的(XML)工具支持几乎没有什么好处。 除此之外,XML还带有性能开销,因此通常slower than code solutions

基于XML和注释的链接:

  1. http://docs.spring.io/spring/docs/current/spring-framework-reference/htmlsingle/#beans-annotation-config
  2. 注释与XML,优点和缺点
  3. Javadependency injection:XML或注释
  4. 基于Spring注释的DI vs xml配置?
  5. Xml配置与基于注释的配置

基于Groovy的链接:

  1. https://objectpartners.com/2016/01/12/using-groovy-based-spring-configuration/
  2. http://blog.andresteingress.com/2014/02/14/grails-java-based-spring-config/

Bean定义:

bean定义有两种方法: 在此处输入图像描述

扫描类路径:

对于xml-config ,它将是用于java-config@ComponentScan注释,用于Groovy ctx.'component-scan'(...)调用。

dependency injection:

在基于xml的配置中, dependency injection可以在xml手动完成,也可以使用annotations (@Autowire,@ Required等)完成。 在这种情况下,需要定义

问与答:

Q1:为什么(所谓的)基于注释的配置实际上使用的是ClassPathXmlApplicationContext而不是AnnotationConfigApplicationContext?

Ans:它是一个基于xml的配置,带有基于注释的bean定义。

应用背景:

  1. http://docs.spring.io/spring/docs/4.2.0.RELEASE/javadoc-api/org/springframework/context/ApplicationContext.html

AnnotationConfigApplicationContext:

1. AnnotationConfigApplicationContext和父上下文

ClassPathXmlApplicationContext的:

  1. http://www.tutorialspoint.com/spring/spring_applicationcontext_container.htm
  2. http://www.mkyong.com/spring3/spring-3-hello-world-example/

Q2:书中解释的基于Java的配置似乎应该称为基于注释的配置。

答:你对那个案子说得对。 基于Java的配置使用注释,并称为基于注释的配置。 但注释是Java的一个部分,没有别的。

但是,我们需要详细了解这个层次结构是如何从基于xml到注释以及最后基于groovy的?

基于注释的配置提供了XML设置的替代方案,该配置依赖于字节码元数据来连接组件而不是角括号声明。 开发人员不是使用XML来描述bean连接,而是通过在相关的类,方法或字段声明上使用注释将配置移动到组件类本身。 正如在“示例:RequiredAnnotationBeanPostProcessor”一节中所提到的,将 BeanPostProcessor与注释结合使用是扩展Spring IoC容器的常用方法。 例如, Spring 2.0引入了使用@Required注释强制执行所需属性的可能性。

Spring 2.5使得有可能采用相同的通用方法来驱动Spring的dependency injection。 从本质上讲,@ @Autowired注释提供的function与第6.4.5节“自动assembly协作者”中描述的function相同,但具有更细粒度的控制和更广泛的适用性。

Spring 2.5还增加了对JSR-250注释的支持,例如@ @PostConstruct@PreDestroy

Spring 3.0增加了对javax.inject包中包含的JSR-330(Java的dependency injection)注释的支持,例如@Inject@Named 。 有关这些注释的详细信息,请参阅相关章节。

问题3:配置Spring框架有多少种方法?

答:

Theoretically, 3种描述配置的方法,以及2种定义bean的方法。 它变为3 * 2 = 6种方式来配置Spring框架(默认情况下)。 所有这些方式都可以相互结合使用。

But Actually,简而言之,我们可以使用XMLannotations来配置spring框架。

我没有看过这本书,但你的假设实际上是正确的。

要启动Spring应用程序并使用XML配置的bean实现框架实例化的所有bean,必须使用ClassPathXmlApplicationContext。

在Spring中有两种配置bean的方法:

1)XML bean 2)注释方法

基本上,Spring bean在Spring 2.5-3中使用,而Annotations方法在Spring 4中使用得更多。

 @Bean // is a way to create a bean. It is the equalivant of the beans tag in XML. @Configuration // is a way to tell the Spring container that this class is a list of configuration beans 

Spring有2个弹簧容器:

1)BeanFactory 2)ApplicationContext

BeanFactory是最简单的容器,只接受一个配置文件。 ApplicationContext是最先进的Spring容器,用于企业应用程序,因为它接受一组配置文件,具有JNDI集成,EJB集成并支持消息的国际化。

我希望有所帮助。

首先让我先说明不同的编码:

  1. XML:您必须使用在xml上下文文件中注册spring bean
  2. Java配置:您必须使用@Configuration@Bean在上下文中注册spring bean。

  3. 注释:通过使用@Component和它的朋友实际上常见的可以与其他2使用:

    1. 在xml中使用
    2. 在java配置中使用@ComponentScan

为什么使用ClassPathXmlApplicationContext因为他使用xml来配置组件扫描,但如果他使用@ComponentScan那么肯定会使用AnnotationConfigApplicationContext

所以对我来说,我认为它是两种初始化spring context xml或java配置的方法,而Annotation is option可以被其中任何一个使用或根本不使用。

配置弹簧框架的三种方式根本不是互斥的。 实际上,我的猜测是,平均而言,你会发现它们中至少有两个一起使用。

基于注释的配置最不可能单独使用,仅仅因为它依赖于本质上分散在整个源代码中的元数据。

AnnotationConfigApplicationContext 可用于启动基于注释的上下文 ,但您需要传入所有注释为@Component或派生@Component ,而不是传入一个(或几个) @Configuration -annotated类( es) – 这通常是不实际的。

虽然这与在XML或Java配置中静态列出bean几乎相同,但是当您构建应用程序上下文时,您需要在代码中执行此操作,这使得它不太有用,因为您无法从中受益各种聪明的方法来自动启动应用程序上下文(在Web上下文等)。

这就是为什么你可能希望能够一次性组装完整的对象图元数据,而这只能通过XML或基于Java的配置来实现 ,这些配置依赖于描述整个对象图的“集中式”元数据。

对于基于XML和Java的方法,可以静态(使用显式@Bean定义)或动态(使用@ComponentScan )定义此“集中式元数据”( @Configuration ) 。 因此可以合理地说,这两种方法只是不同的格式,具有几乎相同的function,这些function都可以从基于注释的配置中受益,以收集“分散的”元数据。