web.xml --> myAppServletContext.xml --> myapp-applicationContext.xml --> MyAppController.java --> MyAppService.Java --> MyAppDaoImpl.java
Pay attention to how the different artifacts are wired up using both Spring xml files and annotations. The Spring beans can be wired either by name or type. @Autowired by default is a type driven injection. @Autowired is Spring annotation, while @Inject is a JSR-330 annotation. @Inject is equivalent to @Autowired or @Autowired(required=true). @Qualifier spring annotation can be used to further fine-tune auto-wiring. There may be a situation when you create more than one bean of the same type and want to wire only one of them with a property, in such case you can use @Qualifier annotation along with @Autowired to remove the confusion by specifying which exact bean will be wired.
The Step 3: demonstrates "name" driven wiring up using annotations.
Step 1: The web.xml file snippet.
<servlet>
<servlet-name>myAppServlet</servlet-name>
<servlet-class>org.springframework.web.servlet.DispatcherServlet</servlet-class>
<init-param>
<param-name>contextConfigLocation</param-name>
<param-value>/META-INF/spring/myAppServletContext.xml</param-value>
</init-param>
<load-on-startup>2</load-on-startup>
</servlet>
<!-- Creates the Spring Container shared by all Servlets and Filters -->
<listener>
<listener-class>org.springframework.web.context.ContextLoaderListener</listener-class>
</listener>
<-- add resolvers here, if required-->
<servlet-mapping>
<servlet-name>myAppServlet</servlet-name>
<url-pattern>/myapp/*</url-pattern>
</servlet-mapping>
Step 2: The myAppServletContext.xml file snippet.
<?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:mvc="http://www.springframework.org/schema/mvc" xmlns:cache="http://www.springframework.org/schema/cache"
xmlns:context="http://www.springframework.org/schema/context"
xmlns:aop="http://www.springframework.org/schema/aop" xmlns:jee="http://www.springframework.org/schema/jee"
xmlns:tx="http://www.springframework.org/schema/tx" xmlns:util="http://www.springframework.org/schema/util"
xmlns:batch="http://www.springframework.org/schema/batch" xmlns:cm="http://camel.apache.org/schema/spring"
xsi:schemaLocation="
http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans-3.1.xsd
http://www.springframework.org/schema/mvc http://www.springframework.org/schema/mvc/spring-mvc-3.1.xsd
http://www.springframework.org/schema/context http://www.springframework.org/schema/context/spring-context-3.1.xsd
http://www.springframework.org/schema/aop http://www.springframework.org/schema/aop/spring-aop-3.1.xsd
http://www.springframework.org/schema/jee http://www.springframework.org/schema/jee/spring-jee-3.1.xsd
http://www.springframework.org/schema/tx http://www.springframework.org/schema/tx/spring-tx-3.1.xsd
http://camel.apache.org/schema/spring http://camel.apache.org/schema/spring/camel-spring.xsd
http://www.springframework.org/schema/context http://www.springframework.org/schema/context/spring-context.xsd
http://www.springframework.org/schema/util http://www.springframework.org/schema/util/spring-util-3.1.xsd
http://www.springframework.org/schema/cache http://www.springframework.org/schema/cache/spring-cache-3.1.xsd">
<!-- import context files as it is not a best practice to define everything in one xml file-->
<import resource="classpath:/META-INF/spring/myapp-applicationContext.xml" />
<!-- scan for any Java based wiring up classes with @Configuration & @Bean annotations -->
<context:component-scan base-package="com.myapp.camel.config" />
<!-- exposing beans via JMX not important for this tutorial -->
<bean id="exporter" class="org.springframework.jmx.export.MBeanExporter"
lazy-init="false">
<property name="autodetect" value="true"></property>
<property name="namingStrategy" ref="namingStrategy"></property>
<property name="assembler" ref="assembler"></property>
</bean>
<bean id="attributeSource"
class="org.springframework.jmx.export.annotation.AnnotationJmxAttributeSource" />
<bean id="assembler"
class="org.springframework.jmx.export.assembler.MetadataMBeanInfoAssembler">
<property name="attributeSource" ref="attributeSource" />
</bean>
<bean id="namingStrategy"
class="org.springframework.jmx.export.naming.MetadataNamingStrategy">
<property name="attributeSource" ref="attributeSource" />
</bean>
</beans>
Step 3: The myapp-applicationContext.xml snippet with config to enable auto-scan with annotations.
As you can see, the controller, service, and DAO layer classes not configured here as they are scanned via annotation (i,e @Component is the parent annotation from which the other annotations like @Service, @Resource, @Repository etc are defined)
The annotations shown above allow you to declare beans that are to be picked up by autoscanning with <context:component-scan/> or @ComponentScan.
<?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:aop="http://www.springframework.org/schema/aop" xmlns:jee="http://www.springframework.org/schema/jee"
xmlns:tx="http://www.springframework.org/schema/tx" xmlns:util="http://www.springframework.org/schema/util"
xmlns:security="http://www.springframework.org/schema/security"
xmlns:batch="http://www.springframework.org/schema/batch" xmlns:task="http://www.springframework.org/schema/task"
xmlns:mvc="http://www.springframework.org/schema/mvc"
xsi:schemaLocation="
http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans-3.1.xsd
http://www.springframework.org/schema/mvc http://www.springframework.org/schema/mvc/spring-mvc-3.1.xsd
http://www.springframework.org/schema/context http://www.springframework.org/schema/context/spring-context-3.1.xsd
http://www.springframework.org/schema/aop http://www.springframework.org/schema/aop/spring-aop-3.1.xsd
http://www.springframework.org/schema/jee http://www.springframework.org/schema/jee/spring-jee-3.1.xsd
http://www.springframework.org/schema/tx http://www.springframework.org/schema/tx/spring-tx-3.1.xsd
http://www.springframework.org/schema/util http://www.springframework.org/schema/util/spring-util-3.1.xsd
http://www.springframework.org/schema/context http://www.springframework.org/schema/context/spring-context-3.1.xsd
http://www.springframework.org/schema/security http://www.springframework.org/schema/security/spring-security-3.1.xsd
http://www.springframework.org/schema/task http://www.springframework.org/schema/task/spring-task-3.1.xsd">
<mvc:annotation-driven />
<context:annotation-config />
<!-- load properties files -->
<bean class="org.springframework.beans.factory.config.PropertyPlaceholderConfigurer">
<property name="ignoreUnresolvablePlaceholders" value="true"/>
<property name="location" value="classpath:/myapp/myapp.properties"/>
<property name="placeholderPrefix" value="$myapp{"/>
<property name="placeholderSuffix" value="}"/>
</bean>
<!-- any packages to exclude for component scanning-->
<context:component-scan base-package="com.myapp">
<context:exclude-filter type="regex" expression="com.myapp.camel.config.MyAppCamelConfig"/>
</context:component-scan>
<!-- comment this line locally to bypass security access control in development. But don't check this in commented as security will be turned off -->
<!-- Spring security-->
<security:global-method-security secured-annotations="enabled" pre-post-annotations="enabled" jsr250-annotations="enabled"/>
</beans>
Step 4: The controller class that handles HTTP requests. Annotations are used to wire up dependencies.
@Controller
public class MyAppController
{
private final MDCLoggingHelper MDCLoggingHelper = new MDCLoggingHelper();
@Resource(name = "myapp_Service")
private MyAppService myAppService;
@RequestMapping(
value = "/portfolio/{portfoliocd}/summaries",
method = RequestMethod.GET,
produces = "application/json")
@ResponseBody
public PortfolioSummaryVO retrievePortfolioSummary(
@PathVariable(value = "portfoliocd") String portfolioCode,
@RequestParam(value = "valuationDate", required = true) @DateTimeFormat(pattern = "yyyyMMdd") Date valuationDate
HttpServletResponse response) throws Exception
{
//..................
}
}
Step 5: The service class that handles business logic in a protocol agnostic manner. Annotations are used to wire up dependencies.
@Service(value = "myapp_Service")
@Transactional(propagation = Propagation.SUPPORTS)
public class CashForecastServiceImpl implements CashForecastService
{
@Resource(name = "myapp_Dao")
private MyAppDao myAppDao;
@Value("$cf{myapp.file_delimiter}")
private String defaultFeedDelimiter; //read from myapp.properties files
@Override
public PortfolioSummaryVO retrievePortfolioSummaries(MyAppPortfolioCriteria criteria,
FeedFileMetaInfo feedFileMeta) {
//..............
}
}
Step 6: The DAO class that makes database calls via a JDBC template. The configuration of JDBC template is not shown.
@Repository(value = "myapp_Dao")
public class CashForecastDaoImpl implements CashForecastDao
{
@Resource(name = "myapp_JdbcTemplate")
private JdbcTemplate jdbcTemplateSybase;//configure via jdbcContext.xml
public PortfolioSummaryVO retrievePortfolioSummaries(MyAppPortfolioCriteria criteria) {
//............
}
}
The @Configuration annotation was designed as the replacement for XML configuration files. The @Configuration annotated classes can still able to use annotated(@Autowired, @Inject etc.) fields and properties to request beans (and even other @Configuration annotated beans too) from the container. Here is an example of how Apache Camel is wired up using the @configuration and @bean annotations in Step 2.