一、扫描顺序
1、项目先读取web.xml文件,根据如下配置读取applicationcontext.xml文件
<context-param>
<param-name>contextConfigLocation</param-name>
<param-value>classpath:applicationcontext.xml</param-value>
</context-param>
2、applicationcontext.xml文件内配置情况
<!-- 读取properties文件内信息,在java中使用@Value(${})注解引入,在xml中使用${}引入使用 -->
<bean id="propertyConfigurer1" class="org.springframework.beans.factory.config.PropertyPlaceholderConfigurer">
<property name="order" value="1" />
<property name="ignoreUnresolvablePlaceholders" value="true"/>
<property name="locations">
<list>
<value>classpath:config.properties</value>
</list>
</property>
</bean>
<context:annotation-config/>
<!-- 自动扫描bean,不扫描controller,交给springmvc扫描 -->
<context:component-scan base-package="com.secoo.pis">
<!-- 扫描带有@Controller注解的类。因为这些类已经随容器启动时,在servlet-context中扫描过 -->
<context:exclude-filter type="annotation" expression="org.springframework.stereotype.Controller"/>
</context:component-scan>
<!-- 引入其他xml文件 -->
<import resource="./datasource.xml"/>
<!-- 自动扫描 将Mapper接口生成代理注入到Spring -->
<bean class="org.mybatis.spring.mapper.MapperScannerConfigurer">
<property name="basePackage" value="org.mybatis.spring.sample.mapper" />
</bean>
3、读取web.xml文件,根据如下配置读取到springmvc-servlet.xml文件
<servlet>
<servlet-name>springmvc</servlet-name>
<servlet-class>org.springframework.web.servlet.DispatcherServlet
</servlet-class>
<init-param>
<param-name>contextConfigLocation</param-name>
<param-value>classpath:springmvc-servlet.xml</param-value>
</init-param>
<load-on-startup>1</load-on-startup>
</servlet>
4、扫描带controller注解的bean
<context:component-scan base-package="com.secoo.pis" use-default-filters="false">
<context:include-filter type="annotation" expression="org.springframework.stereotype.Controller"/>
</context:component-scan>
二、spring和springmvc扫描注解的关系
答:spring和springmvc是父子容器,spring作为父容器优先加载,扫描service层和dao层,不能访问子容器的bean;springmvc作为子容器在spring容器加载完成之后再加载,扫描controller层,能够访问父容器的bean。所以controller能调service和dao,但service和dao不能调controller。springmvc不扫描service和dao的原因是事务作为springAOP的特性,配置在spring文件中,springmvc扫描service和dao则事务失效。springmvc扫描controller是因为控制controller跳转的配置写在springmvc配置文件中,springmvc不扫描controller则访问url不能正常跳转。
ps:无论是spring还是springmvc只会扫描有注解的bean
三、为什么能区分conf-dev、conf-test、conf-pro文件夹
答:在pom.xml配置了profile属性
<profiles>
<profile>
<id>dev</id>
<activation>
<activeByDefault>true</activeByDefault>
</activation>
<properties>
<ver_type>-DEV-SNAPSHOT</ver_type>
</properties>
<build>
<resources>
<resource>
<directory>${project.basedir}/conf_dev/</directory>
</resource>
</resources>
</build>
</profile>
<profile>
<id>test</id>
<properties>
<ver_type>-SNAPSHOT</ver_type>
</properties>
<build>
<resources>
<resource>
<directory>${project.basedir}/conf_test/</directory>
</resource>
</resources>
</build>
</profile>
<profile>
<id>pro</id>
<properties>
<ver_type>.RELEASE</ver_type>
</properties>
<build>
<resources>
<resource>
<directory>${project.basedir}/conf_deploy/</directory>
</resource>
</resources>
</build>
</profile>
</profiles>
<build>
<resources>
<resource>
<directory>${project.basedir}/src/main/java</directory>
<filtering>true</filtering>
<includes>
<include>**/*.xml</include>
<include>**/*.properties</include>
</includes>
</resource>
<resource>
<directory>${project.basedir}/src/main/resources</directory>
<filtering>true</filtering>
<includes>
<include>**/**</include>
</includes>
</resource>
</resources>
</build>
四、为什么自动注入要注入接口而不是实现类?
答:开发中会对实现类做增强,如事务,日志等,实现增强的AOP技术是通过动态代理实现的,而spring默认是JDK动态代理,对实现类对象做增强得到的增强类与实现类是兄弟关系,所以不能用实现类接收增强类对象,只能用接口接收。想要注入实现类则必须将代理模式改为Cglib代理
<aop:aspectj-autoproxy proxy-target-class="true"/>
ps:若是一个普通bean没有接口,则可以直接注入
五、BeanFactory和FactoryBean的区别
答:两者无任何关系
BeanFactory,bean的工厂类,是Ioc容器的核心接口,为Ioc容器确立了规范。他的子接口有ApplicationContext,实现类ClassPathXmlApplicationContext。
FactoryBean,工厂bean,区别于普通bean