我用一个Autowriter去注解一个属性,而且我没有在Spring的配置文件中的bean.xml中注册bean(<bean id=""...);那么这个注解有用吗?答案是不行。也就是说要用Autowriter注解时,其实必须要保证在bean容器中注册过这个bean.
bean在bean容器中的注册分为两种:
1.手动:就是在spring.xml配置文件中,写上
<bean id="configa" class="com.guiugu.shen.bean2.HelloService"> </bean>
2.自动注册,那就是要用自动扫描了。在spring.xml配置文件中写上:
<context:component-scan base-package="com.guiugu.shen.bean2"/>
自动扫描时:会去com.guiugu.shen.bean2这个包下面去寻找有没有被
@Service用于标注业务层组件
@Controller用于标注控制层组件
@Repository用于标注数据访问组件,即DAO组件
@Component泛指组件,当组件不好归类的时候,我们可以使用这个注解进行标注。
这些注解修饰过,有的话就会被自动注册到bean容器中。
只有用以上其中一个方法注册过才会用@Autowriter是有用。
案例如下:
案例结构:
先给出错误案例:
我最先的想法是:只要在applicationContext.xml中配一个自动扫描包,就可以了。如下
applicationContext.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" xmlns:aop="http://www.springframework.org/schema/aop" xmlns:tx="http://www.springframework.org/schema/tx" xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans-3.0.xsd http://www.springframework.org/schema/context http://www.springframework.org/schema/context/spring-context-3.0.xsd http://www.springframework.org/schema/aop http://www.springframework.org/schema/aop/spring-aop-3.0.xsd http://www.springframework.org/schema/tx http://www.springframework.org/schema/tx/spring-tx-3.0.xsd" default-lazy-init="true"> <context:component-scan base-package="com.guiugu.shen.bean2"/> </beans>
HelloService.java:
package com.guiugu.shen.bean2; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.stereotype.Component; import org.springframework.stereotype.Service; public class HelloService { public void sayHello() { System.out.print("hello"); } }
TestJavaSpring.java代码:
package com.guiugu.shen.bean2;
import org.junit.Test;
import org.junit.runner.RunWith;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Component;
import org.springframework.test.context.ContextConfiguration;
import org.springframework.test.context.junit4.SpringJUnit4ClassRunner;
@RunWith(SpringJUnit4ClassRunner.class)
@ContextConfiguration(locations = "classpath:applicationContextt.xml")
public class TestJavaSpring {
@Autowired
private HelloService helloService;
@Test
public void testSayhell()
{
helloService.sayHello();
}
}
运行结果:
Caused by: org.springframework.beans.factory.NoSuchBeanDefinitionException: No matching bean of type [com.guiugu.shen.bean2.HelloService] found for dependency: expected at least 1 bean which qualifies as autowire candidate for this dependency. Dependency annotations: {@org.springframework.beans.factory.annotation.Autowired(required=true)}
很明显:上面的结果是找不到对应的bean.因为没有在bean容器中注册bean.
两个解决办法:1.手动在applicationContext.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" xmlns:aop="http://www.springframework.org/schema/aop" xmlns:tx="http://www.springframework.org/schema/tx" xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans-3.0.xsd http://www.springframework.org/schema/context http://www.springframework.org/schema/context/spring-context-3.0.xsd http://www.springframework.org/schema/aop http://www.springframework.org/schema/aop/spring-aop-3.0.xsd http://www.springframework.org/schema/tx http://www.springframework.org/schema/tx/spring-tx-3.0.xsd" default-lazy-init="true"> <!-- 手动注册这个bean > <bean id="configa" class="com.guiugu.shen.bean2.HelloService"> </bean> </beans>
运行结果:正确。输出为hello。因为手动注册过了这个bean。
第二种解决办法:在applicationContext.xml用自动扫描器去扫描包。并且在HelloService上用@Component,因为这样自动扫描包才能识别。自动扫描包能识别的注解是:
@Service@Controller@Repository@Component。
ApplicationContext.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" xmlns:aop="http://www.springframework.org/schema/aop" xmlns:tx="http://www.springframework.org/schema/tx" xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans-3.0.xsd http://www.springframework.org/schema/context http://www.springframework.org/schema/context/spring-context-3.0.xsd http://www.springframework.org/schema/aop http://www.springframework.org/schema/aop/spring-aop-3.0.xsd http://www.springframework.org/schema/tx http://www.springframework.org/schema/tx/spring-tx-3.0.xsd" default-lazy-init="true">
<--扫描到之后会自动会去注册bean-->
<context:component-scan base-package="com.guiugu.shen.bean2"/> </beans>
HelloService代码:
package com.guiugu.shen.bean2; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.stereotype.Component; import org.springframework.stereotype.Service; @Component public class HelloService { public void sayHello() { System.out.print("hello"); } }
TestJavaSpring.java:
package com.guiugu.shen.bean2; import org.junit.Test; import org.junit.runner.RunWith; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.stereotype.Component; import org.springframework.test.context.ContextConfiguration; import org.springframework.test.context.junit4.SpringJUnit4ClassRunner; @RunWith(SpringJUnit4ClassRunner.class) @ContextConfiguration(locations = "classpath:applicationContextt.xml") public class TestJavaSpring { @Autowired private HelloService helloService; @Test public void testSayhell() { helloService.sayHello(); } }
运行结果正确。
上面的执行流程是:
Spring启动,然后根据<context:component-scan base-package="com.guiugu.shen.bean2"/>去这个包下面去寻找被@Service@Controller@Repository@Component注册类,找到的话就把他自动注册到bean容器中。
这样当我们执行
@Autowired
private HelloService helloService;
就会从bean容器中把对应的类取出来实例化(因为之前已经注册进去了)