Spring 注解配置(annotation-config、component-scan和annotation-driven的不同)

本文详细解析了Spring MVC框架中的XML配置元素,包括context:annotation-config、context:component-scan和mvc:annotation-driven等,阐述了它们的功能差异及应用场景。

Spring 的xml配置里如何仅通过注解使用(annotation-config 和 component-scan的不同) 这个问题也算看了好几遍还没记住的问题,先抛结论,如果是为在Spring中声明注解,不需xml配置的话,使用<context:component-scan base-package="com">类似的就可以实现无bean声明。 然后,我们详细说下这两个配置的作用:

  • context:annotation-config/的作用:它是对已注册Bean的进行操作的配置,也就是说,Bean需要首先通过某种方式(比如Xml配置,或者其他注解)被注册,然后使用这个配置,可以对已注册的Bean进行进一步操作(比如注入到某个类的内部),也就是说,这个配置是用于“激活”已注册的Bean的,让已注册的Bean开始工作。
  • <context:component-scan />的作用:<context:component-scan />首先有和context:annotation-config/一样的作用,此外,它还可以扫描指定包下的类,将拥有注解的它们注册到Spring中。 综上,也就是说,如果用context:annotation-config/,我们还需要配置Xml注册Bean,而使用<context:component-scan />的话,注册的步骤都免了,当然前提是我们对需要扫描的类使用的注解(比如@Componet,@Service),而如果同时使用两个配置的话,context:annotation-config/会被忽略掉。

Java developers can avail different configuration elements from Spring MVC framework to handle the beans and inject them when required. In this article, they will make you learn about XML configurations used in Spring MVC, advantages, and disadvantages, and uses in detail. To gain knowledge about the same, read the post thoroughly.

Spring MVC framework provides different configuration elements that are helping or instructing the Spring container to effectively manage the beans and inject the beans when required. Some of the XML configurations that are most commonly seen in our spring configuration files are:

context:component-scan
mvc:annotation-config
context:annotation-driven
context:annotation-config is used to activate applied annotations in already registered beans in application context.

context:component-scancan also do what context:annotation-config does but context:component-scan also scans packages to find and register beans within the application context.

The functionality of the above annotations are similar and there is little variations on how they are reacting on the specific scenarios.

Advantages and Disadvantages:

The often sighted “pro” of annotation is that they are attached to the program artifacts they describe. 1) This gives the metadata information relevance that is not always there when viewed in an XML file. 2) However, when searching an application for all the applicable and like program characteristics, an XML document makes the search concise.

Annotations can replace XML deployment descriptors and configurations. 1) Annotations are typically much simpler to code than XML. 2) XML is not always the easiest of documents to read or maintain and it is often very verbose.

Some configuration/deployment information can now be shared across programming environments. 1) Annotations, as part of the actual source code, will not support and promote any cross-platform sharing.

Uses Of Annotation-Config, Annotation-Driven And Component-Scan

annotation-config allow us to use @Autowire, @Required and @Qualifier annotations. component-scan allow @Component, @Service, @Controller, etc.. annotations. annotation-driven <mvc:annotation-driven /> declares explicit support for annotation-driven MVC controllers (i.e. @RequestMapping, @Controller, although support for those is the default behaviour), as well as adding support for declrative validation via @Valid and message body marshalling with @RequestBody/ResponseBody.

  1. context:component-scan

This element has been introduced in Spring configuration from version 2.5. If you have worked with the previous versions of Spring, all the beans has to be manually configured in the XML files.

There are no annotations supported in the Java beans. This will result in lot of XML code in the configuration files and every time developer has to update the XML file for configuring the new beans.

context:component-scan element in the spring configuration file would eliminate the need for declaring all the beans in the XML files. Below declaration in your spring configuration file:

<context:component-scan base-package="org.controller"/>

复制代码

The above declaration in the spring application configuration file would scan the classes inside the specified package and create the beans instance.

The following are the annotations scanned by this element:

@Component @Repository @Service @Controller One advantage of this element is that it also resolves @Autowired and @Qualifier annotations. Therefore if you declare context:component-scan, is not necessary anymore declare context:annotation-config too.

  1. mvc:annotation- config mvc:annotation-driven is used for enabling the Spring MVC components with its default configurations.

If you don’t include mvc:annotation-driven then also your MVC application would work, if you have used the context:component-scan for creating the beans or defined the beans in your XML file.

But, mvc:annotation-driven does some extra job on configuring the special beans that would not have been configured if you are not using this element in your XML file.

This tag would register the HandlerMapping and HandlerAdapter required to dispatch requests to your @Controllers. In addition, it also applies some defaults based on what is present in your classpath.

Such defaults are:

Using the Spring 3 Type ConversionService as a simpler and more robust alternative to JavaBeans PropertyEditors Support for formatting Number fields with @NumberFormat Support for formatting Date, Calendar, and Joda Time fields with @DateTimeFormat, if Joda Time is on the classpath Support for validating @Controller inputs with @Valid, if a JSR-303 Provider is on the classpath Support for reading and writing XML, if JAXB is on the classpath Support for reading and writing JSON, if Jackson is on the classpath 3) context:annotation-driven context:annotation-config is used for activating annotations in beans already registered in the application context.

That means it will resolve @Autowired and @Qualifier annotations for the beans which are already created and stored in the spring container.

context:component-scan can also do the same job, but context:component-scan will also scan the packages for registering the beans to application context.

context:annotation-config will not search for the beans registration, this will only activate the already registered beans in the context.

Example of context:annotation-config context:component-scan

I will elaborate both tags in detail with some examples which will make more sense to us.

For reference, below are 3 beans. BeanA has reference to BeanB and BeanC additionally.

package com.example.beans;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Component;

@SuppressWarnings("unused")
@Component
public class BeanA {
    private BeanB beanB;
    private BeanC beanC;
    public BeanA(){
        System.out.println("Creating bean BeanA");
    }
    @Autowired
    public void setBeanB(BeanB beanB) {
        System.out.println("Setting bean reference for BeanB");
        this.beanB = beanB;
    }
    @Autowired
    public void setBeanC(BeanC beanC) {
        System.out.println("Setting bean reference for BeanC");
        this.beanC = beanC;
    }
}

//Bean B  
package com.example.beans;
import org.springframework.stereotype.Component;
@Component
public class BeanB {
    public BeanB(){
        System.out.println("Creating bean BeanB");
    }
}

//Bean C
package com.example.beans;
import org.springframework.stereotype.Component;
@Component
public class BeanC {
    public BeanC(){
        System.out.println("Creating bean BeanC");
    }
}

复制代码

BeanDemo class is used to load and initialize the application context.

package com.example.test;
import org.springframework.context.ApplicationContext;
import org.springframework.context.support.ClassPathXmlApplicationContext;
public class BeanDemo {
    public static void main(String[] args) {
        ApplicationContext context = new ClassPathXmlApplicationContext("classpath:beans.xml");
    }
}

复制代码

a) Define only bean tags

<bean id="beanA" class="com.example.beans.BeanA"></bean>
<bean id="beanB" class="com.example.beans.BeanB"></bean>
<bean id="beanC" class="com.example.beans.BeanC"></bean>

复制代码

Output: Creating bean BeanA

Creating bean BeanB

Creating bean BeanC

In this case, all 3 beans are created and no dependency in injected in BeanA because we didn’t used any property/ref attributes.

b) Define bean tags and property ref attributes

<bean id="beanA" class="com.example.beans.BeanA">
    <property name="beanB" ref="beanB"></property>
    <property name="beanC" ref="beanC"></property>
</bean>
<bean id="beanB" class="com.example.beans.BeanB"></bean>
<bean id="beanC" class="com.example.beans.BeanC"></bean>

复制代码

Output:

Creating bean BeanA

Creating bean BeanB

Creating bean BeanC

Setting bean reference for BeanB

Setting bean reference for BeanC

Now the beans are created and injected as well.

c) Using only <context:annotation-config />

<context:annotation-config />

复制代码

//No Output

<context:annotation-config /> activate the annotations only on beans which have already been discovered and registered. Here, we have not discovered any bean so nothing happened.

d) Using <context:annotation-config /> with bean declarations

<context:annotation-config />
<bean id="beanA" class="com.example.beans.BeanA"></bean>
<bean id="beanB" class="com.example.beans.BeanB"></bean>
<bean id="beanC" class="com.example.beans.BeanC"></bean>

复制代码

Output:

Creating bean BeanA

Creating bean BeanB

Setting bean reference for BeanB

Creating bean BeanC

Setting bean reference for BeanC

In above configuration, we have discovered the beans using tags. Now when we use <context:annotation-config />, it simply activates @Autowired annotation and bean injection inside BeanA happens.

e) Using only <context:component-scan />

<context:component-scan base-package="com.example.beans" />

复制代码

Output:

Creating bean BeanA

Creating bean BeanB

Setting bean reference for BeanB

Creating bean BeanC

Setting bean reference for BeanC

Above configuration does both things as I mentioned earlier in start of post. It does the bean discovery (searches for @Component annotation in base package) and then activates the additional annotations (e.g. Autowired).

f) Using both <context:component-scan /> and <context:annotation-config />

<context:annotation-config />
<context:component-scan base-package="com.example.beans" />
<bean id="beanA" class="com.example.beans.BeanA"></bean>
<bean id="beanB" class="com.example.beans.BeanB"></bean>
<bean id="beanC" class="com.example.beans.BeanC"></bean>

复制代码

Output:

Creating bean BeanA

Creating bean BeanB

Setting bean reference for BeanB

Creating bean BeanC

Setting bean reference for BeanC

Example of mvc:annotation-driven

<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans"
       xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
       xmlns:p="http://www.springframework.org/schema/p"
       xmlns:context="http://www.springframework.org/schema/context"
       xmlns:mvc="http://www.springframework.org/schema/mvc"
       xsi:schemaLocation="http://www.springframework.org/schema/beans

http://www.springframework.org/schema/beans/spring-beans.xsd

http://www.springframework.org/schema/context

http://www.springframework.org/schema/context/spring-context.xsd

http://www.springframework.org/schema/mvc

                           http://www.springframework.org/schema/mvc/spring-mvc.xsd">

    <context:component-scan base-package="org.springbyexample.web.servlet.mvc" />

    <mvc:annotation-driven />

<mvc:view-controller path="/index.html" />

    <bean id="tilesConfigurer"
          class="org.springframework.web.servlet.view.tiles2.TilesConfigurer"
          p:definitions="/WEB-INF/tiles-defs/templates.xml" />

    <bean id="tilesViewResolver"
          class="org.springframework.web.servlet.view.UrlBasedViewResolver"
          p:viewClass="org.springbyexample.web.servlet.view.tiles2.DynamicTilesView"
          p:prefix="/WEB-INF/jsp/"
          p:suffix=".jsp" />

    <bean id="messageSource" class="org.springframework.context.support.ResourceBundleMessageSource"
          p:basenames="messages" />

    <!-- Declare the Interceptor -->
    <mvc:interceptors>    
        <bean class="org.springframework.web.servlet.i18n.LocaleChangeInterceptor"
              p:paramName="locale" />
    </mvc:interceptors>
    
    <!-- Declare the Resolver -->
    <bean id="localeResolver" class="org.springframework.web.servlet.i18n.SessionLocaleResolver" />

</beans>

复制代码

You have just learned about advantages, disadvantages, and uses of XML configurations used in Spring MVC framework by Java developers. For any doubts or queries, please comment in below section. We will give you the required solutions.

转载于:https://juejin.im/post/5af8616cf265da0ba60fe559

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值