spring的依赖注入
spring的依赖注入有:
1、手工装配(注入值自己编写配置,注解@Autowired @Resource
2、自动装配
关于注解的方式注入
1、首先xml文档里面得加上一个命名空间
xmlns:context="http://www.springframework.org/schema/context"
http://www.springframework.org/schema/context
http://www.springframework.org/schema/context/spring-context.xsd"
这个是为了使用
<context:annotation-config />
2、由于@Resource和@Autowired的功能差不多
@Resource 默认是按照名称来寻找相应的bean对象,如果按名称找不到对象就会转而用类型来寻找对象
@Autowired默认是使用类型来寻找对象的
并且@Resource是j2ee的一个包,不是spring里面的,所以解耦比Autowired比较好,所以建议使用@Resource
使用@Resource注入
比如一个类里面有这么两个数据成员:
private PersonDao personDao;
private String name = "cutter_point";
那么要对personDao如何进行注入呢?
@Resource private PersonDao personDao; //通过注释来进行注入
这样,在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:annotation-config />
<bean id="personDao" class="cn.dao.impl.PersonDaoBean"></bean>
<bean id="personService" class="cn.service.impl.PersonServiceBean"></bean>
</beans>
我们在JUnit里面调用一下函数
package cn.service.impl;
import java.util.HashSet;
import java.util.Set;
import javax.annotation.Resource;
import cn.dao.PersonDao;
import cn.service.PersonService;
public class PersonServiceBean implements PersonService {
@Resource private PersonDao personDao; //通过注释来进行注入
private String name = "cutter_point";
public PersonServiceBean()
{
// TODO Auto-generated constructor stub
}
/**
* @author xiaofeng
* @param 这个是可以生成的构造器
*/
public PersonServiceBean(PersonDao personDao, String name)
{
this.personDao = personDao;
this.name = name;
}
public void save(){
System.out.println(name);
personDao.add();
}
}
调用里面的save方法
package junit.test;
import org.junit.BeforeClass;
import org.junit.Test;
import org.springframework.context.support.AbstractApplicationContext;
import org.springframework.context.support.ClassPathXmlApplicationContext;
import cn.itcast.service.PersonService;
public class SpringTest {
@BeforeClass
public static void setUpBeforeClass() throws Exception {
}
@Test public void instanceSpring()
{
AbstractApplicationContext ctx = new ClassPathXmlApplicationContext("beans.xml");
PersonService personService = (PersonService)ctx.getBean("personService");
personService.save();
ctx.close();
}
}
如果注入失败,那么调用
personService.save();
就会报错,空指针错误,比如我们把xml文档中的
<bean id="personDao" class="cn.itcast.dao.impl.PersonDaoBean"></bean>
注释掉,程序报错:
org.springframework.beans.factory.BeanCreationException: Error creating bean with name 'personService': Injection of resource methods failed; nested exception is org.springframework.beans.factory.NoSuchBeanDefinitionException: No unique bean of type [cn.itcast.dao.PersonDao] is defined: Unsatisfied dependency of type [interface cn.itcast.dao.PersonDao]: expected at least 1 matching bean
at org.springframework.context.annotation.CommonAnnotationBeanPostProcessor.postProcessPropertyValues(CommonAnnotationBeanPostProcessor.java:305)
at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.populateBean(AbstractAutowireCapableBeanFactory.java:998)
at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.doCreateBean(AbstractAutowireCapableBeanFactory.java:472)
at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory$1.run(AbstractAutowireCapableBeanFactory.java:409)
at java.security.AccessController.doPrivileged(Native Method)
at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.createBean(AbstractAutowireCapableBeanFactory.java:380)
at org.springframework.beans.factory.support.AbstractBeanFactory$1.getObject(AbstractBeanFactory.java:264)
at org.springframework.beans.factory.support.DefaultSingletonBeanRegistry.getSingleton(DefaultSingletonBeanRegistry.java:222)
at org.springframework.beans.factory.support.AbstractBeanFactory.doGetBean(AbstractBeanFactory.java:261)
at org.springframework.beans.factory.support.AbstractBeanFactory.getBean(AbstractBeanFactory.java:185)
at org.springframework.beans.factory.support.AbstractBeanFactory.getBean(AbstractBeanFactory.java:164)
at org.springframework.beans.factory.support.DefaultListableBeanFactory.preInstantiateSingletons(DefaultListableBeanFactory.java:429)
at org.springframework.context.support.AbstractApplicationContext.finishBeanFactoryInitialization(AbstractApplicationContext.java:728)
at org.springframework.context.support.AbstractApplicationContext.refresh(AbstractApplicationContext.java:380)
at org.springframework.context.support.ClassPathXmlApplicationContext.<init>(ClassPathXmlApplicationContext.java:139)
at org.springframework.context.support.ClassPathXmlApplicationContext.<init>(ClassPathXmlApplicationContext.java:83)
at junit.test.SpringTest.instanceSpring(SpringTest.java:18)
at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:57)
at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
at java.lang.reflect.Method.invoke(Method.java:606)
at org.junit.runners.model.FrameworkMethod$1.runReflectiveCall(FrameworkMethod.java:44)
at org.junit.internal.runners.model.ReflectiveCallable.run(ReflectiveCallable.java:15)
at org.junit.runners.model.FrameworkMethod.invokeExplosively(FrameworkMethod.java:41)
at org.junit.internal.runners.statements.InvokeMethod.evaluate(InvokeMethod.java:20)
at org.junit.runners.BlockJUnit4ClassRunner.runChild(BlockJUnit4ClassRunner.java:76)
at org.junit.runners.BlockJUnit4ClassRunner.runChild(BlockJUnit4ClassRunner.java:50)
at org.junit.runners.ParentRunner$3.run(ParentRunner.java:193)
at org.junit.runners.ParentRunner$1.schedule(ParentRunner.java:52)
at org.junit.runners.ParentRunner.runChildren(ParentRunner.java:191)
at org.junit.runners.ParentRunner.access$000(ParentRunner.java:42)
at org.junit.runners.ParentRunner$2.evaluate(ParentRunner.java:184)
at org.junit.internal.runners.statements.RunBefores.evaluate(RunBefores.java:28)
at org.junit.runners.ParentRunner.run(ParentRunner.java:236)
at org.eclipse.jdt.internal.junit4.runner.JUnit4TestReference.run(JUnit4TestReference.java:50)
at org.eclipse.jdt.internal.junit.runner.TestExecution.run(TestExecution.java:38)
at org.eclipse.jdt.internal.junit.runner.RemoteTestRunner.runTests(RemoteTestRunner.java:467)
at org.eclipse.jdt.internal.junit.runner.RemoteTestRunner.runTests(RemoteTestRunner.java:683)
at org.eclipse.jdt.internal.junit.runner.RemoteTestRunner.run(RemoteTestRunner.java:390)
at org.eclipse.jdt.internal.junit.runner.RemoteTestRunner.main(RemoteTestRunner.java:197)
Caused by: org.springframework.beans.factory.NoSuchBeanDefinitionException: No unique bean of type [cn.itcast.dao.PersonDao] is defined: Unsatisfied dependency of type [interface cn.itcast.dao.PersonDao]: expected at least 1 matching bean
at org.springframework.beans.factory.support.DefaultListableBeanFactory.resolveDependency(DefaultListableBeanFactory.java:613)
at org.springframework.context.annotation.CommonAnnotationBeanPostProcessor.autowireResource(CommonAnnotationBeanPostProcessor.java:431)
at org.springframework.context.annotation.CommonAnnotationBeanPostProcessor.getResource(CommonAnnotationBeanPostProcessor.java:409)
at org.springframework.context.annotation.CommonAnnotationBeanPostProcessor$ResourceElement.getResourceToInject(CommonAnnotationBeanPostProcessor.java:537)
at org.springframework.beans.factory.annotation.InjectionMetadata$InjectedElement.inject(InjectionMetadata.java:192)
at org.springframework.beans.factory.annotation.InjectionMetadata.injectMethods(InjectionMetadata.java:117)
at org.springframework.context.annotation.CommonAnnotationBeanPostProcessor.postProcessPropertyValues(CommonAnnotationBeanPostProcessor.java:302)
... 39 more
但是如果去掉注释
注入成功!!
关于set方法注入
//使用set方法注释注入
@Resource
public void setPersonDao(PersonDao personDao)
{
this.personDao = personDao;
}
效果和
@Resource private PersonDao personDao; //通过注释来进行注入
一样!!!