<context:annotation-config> 是用于激活那些已经在spring容器里注册过的bean(无论是通过xml的方式还是通过packagesanning的方式)上面的注解。(激活@Resource和@Autowired注解)
<context:component-scan>除了具有<context:annotation-config>的功能之外,<context:component-scan>还可以在指定的package下扫描以及注册javabean 。(激活@Resource和@Autowired注解,同时可以配置扫描的包以激活@Service、@Controller等注解)
1.<context:component-scan>的作用:(开发中用这一个足以)
一方面可以配置扫描注解的包的路径,另一方面具有<context:annotation-config>的作用,也就是可以实现注解注入(Autowired与Resource等注解)。
例如:
目录结构:
ApplicationContext-test.xml
<?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:context="http://www.springframework.org/schema/context" 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"> <!--配置扫描注解的包--> <context:component-scan base-package="cn.qlq.test" ></context:component-scan> </beans>
package cn.qlq.test.dao; import org.springframework.stereotype.Repository; /** * @Author: qlq * @Description * @Date: 22:49 2018/9/28 */ @Repository public class UserDao { public void saveUser() { System.out.println("save user"); } }
package cn.qlq.test.service; import cn.qlq.test.dao.UserDao; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.stereotype.Service; /** * @Author: qlq * @Description * @Date: 22:52 2018/9/28 */ @Service public class UserService { @Autowired private UserDao userDao; public void saveUser() { userDao.saveUser(); } }
测试类:
package cn.qlq.test; import cn.qlq.test.service.UserService; import org.apache.xbean.spring.context.ClassPathXmlApplicationContext; /** * @Author: qlq * @Description * @Date: 22:54 2018/9/28 */ public class TestApp { public static void main(String[] args) { ClassPathXmlApplicationContext applicationContext = new ClassPathXmlApplicationContext("ApplicationContext-test.xml"); //第一种:用beanId获取bean // UserService userService = (UserService) applicationContext.getBean(UserService.class); //第二种:用bean的class获取bean UserService userService = (UserService) applicationContext.getBean(UserService.class); userService.saveUser(); } }
结果:
save user
补充:
<context:component-scan....可以扫描多个包,逗号隔开就行,而且扫描包的时候会自动扫描子包。如下也是正确的:
<?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:context="http://www.springframework.org/schema/context" 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"> <!--配置扫描注解的包--> <context:component-scan base-package="cn.qlq.test.dao,cn.qlq.test.service" ></context:component-scan> </beans>
2.<context:annotation-config>的作用与测试
<context:annotation-config> 是用于激活那些已经在spring容器里注册过的bean(无论是通过xml的方式还是通过package sanning的方式)上面的注解。也就是激活@Autowired和@Resource注解。但是不会扫描@Service等注解配置的bean。
如下:
<?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:context="http://www.springframework.org/schema/context" 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"> <context:annotation-config/> <bean id="userDao" class="cn.qlq.test.dao.UserDao"/> <bean id="userService" class="cn.qlq.test.service.UserService"/> </beans>
package cn.qlq.test.dao; import org.springframework.stereotype.Repository; /** * @Author: qlq * @Description * @Date: 22:49 2018/9/28 */ public class UserDao { public void saveUser() { System.out.println("save user"); } }
package cn.qlq.test.service; import cn.qlq.test.dao.UserDao; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.stereotype.Service; /** * @Author: qlq * @Description * @Date: 22:52 2018/9/28 */ public class UserService { @Autowired private UserDao userDao; public void saveUser() { userDao.saveUser(); } }
测试代码同上,可以正常运行。
如果我们修改xml为下面:(去掉bean定义)
<?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:context="http://www.springframework.org/schema/context" 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"> <!--配置扫描注解的包--> <context:annotation-config/> </beans>
结果报错没有找到bean:
Exception in thread "main" org.springframework.beans.factory.NoSuchBeanDefinitionException: No qualifying bean of type [cn.qlq.test.service.UserService] is defined at org.springframework.beans.factory.support.DefaultListableBeanFactory.getBean(DefaultListableBeanFactory.java:371) at org.springframework.beans.factory.support.DefaultListableBeanFactory.getBean(DefaultListableBeanFactory.java:331) at org.springframework.context.support.AbstractApplicationContext.getBean(AbstractApplicationContext.java:972) at cn.qlq.test.TestApp.main(TestApp.java:17)
修改xml为如下:(去掉annotation-config标签)
<?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:context="http://www.springframework.org/schema/context" 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"> <bean id="userDao" class="cn.qlq.test.dao.UserDao"/> <bean id="userService" class="cn.qlq.test.service.UserService"/> </beans>
结果会报空指针异常,service中没有注入dao:
Exception in thread "main" java.lang.NullPointerException at cn.qlq.test.service.UserService.saveUser(UserService.java:17) at cn.qlq.test.TestApp.main(TestApp.java:18)