Spring IOC(XML和注解)

      一:依赖注入 

      通过第一个Spring程序之后,创建对象的工作会交给Spring来完成,只需要在配置文件上配置相关的<bean>节点,通过Spring容器就可以根据配置创建对象。

       回顾上一个spring配置文件:

        <bean name="UserDao" class="yzr.dao.UserDao" ></bean>
	<bean name="UserService" class="yzr.service.UserService" >
		<property name="userDao" ref="UserDao"></property>
	</bean>
	<bean name="UserAction" class="yzr.action.UserAction" >
		<property name="userService" ref="UserService"></property>
	</bean>
      这种是通过属性方式的依赖注入,在<bean>节点内包含<property>节点,指定相应的依赖关系。在这种情况下,在Service中需要声明一个关于UserDao的set方法,就像这样:

package yzr.service;

import yzr.dao.UserDao;

public class UserService {
	private UserDao userDao=null;
	public void setUserDao(UserDao userdao){
		userDao=userdao;
	}
	public void run(){
		userDao.run();
		System.out.println("Service执行Run");
	}
}
注意的地方是,<property name="userDao" ref="UserDao"></property>中name的值为userDao,与Service类中的属性变量userDao必须一致,注意大小写。

     除了上面这种通过属性依赖注入的方式,还有另外一种通过构造函数注入依赖,使用<constructor-arg>节点。

        <bean name="UserDao" class="yzr.dao.UserDao" ></bean>
	<!-- 
	<bean name="UserService" class="yzr.service.UserService" >
		<property name="userDao" ref="UserDao"></property>
	</bean>
	-->
	<bean name="UserService" class="yzr.service.UserService" >
		<constructor-arg ref="UserDao"></constructor-arg>
	</bean>
	<bean name="UserAction" class="yzr.action.UserAction" >
		<property name="userService" ref="UserService"></property>
	</bean>
      通过构造函数注入的话,Service需要提供一个带依赖类型的构造函数,比如这样:

package yzr.service;

import yzr.dao.UserDao;

public class UserService {
	private UserDao userDao=null;
	/*
	public void setUserDao(UserDao userdao){
		userDao=userdao;
	}
	*/
	public void run(){
		userDao.run();
		System.out.println("Service执行Run");
	}
	
	public UserService(){
		
	}
        public UserService(UserDao userDao){
    	       this.userDao=userDao;
	}
}

      通过上面两个例子可以往被创建对象注入值(或者对象),此外,假若当需要注入的依赖为集合或者map类型时,spring也提供了相应的节点配置,下面使用属性注入方式说明:

      1.注入List集合:

      1)将String类型值注入集合中用value节点

      <bean name="UserAction" class="yzr.action.UserAction" >
		<property name="userService" ref="UserService"></property>
		<property name="stringList">
                    <list>
                        <value>YZR</value>
                    </list>
                 </property>
	</bean>
      相应的Action中声明一个stringList属性变量:

        private List stringList=null;
	public void setStringList(List actionList) {
		this.stringList = actionList;
	}
      2)将对象类型注入集合中,使用bean节点

       <property name="beanList">
                    <list>
                    	<bean id="Userbean" class="yzr.entity.UserBean">
	  	               <property name="name" value="YZR"></property>
	                </bean>
                    </list>
        </property>
     
      相应的Action中声明一个beanList属性变量:

        private List beanList=null;
	public void setBeanList(List beanList) {
		this.beanList = beanList;
	}
      3)使用ref注入已有的bean
 <bean name="UserAction" class="yzr.action.UserAction" >
		
        <property name="beanList">
                    <list>
                    	<ref bean="Userbean"/>
                    	
                    </list>
        </property>
</bean>
<bean id="Userbean" class="yzr.entity.UserBean">
     <property name="name" value="YZR"></property>
</bean>

    2.注入Map键值对:

    同理 与List,下面三种方式就写在一起表示:

        <property name="maps">
            <map>
                <entry key="StringKey" value="1" />
                <entry key="BeanKey" value-ref="Userbean" />
                <entry key="BeanKey2">
                    <bean id="Userbean" class="yzr.entity.UserBean">
	  	        <property name="name" value="YZR"></property>
	            </bean>
                </entry>
            </map>
        </property>
    3.注入prop属性文件的键值对:

    propertise属性文件的内容只能是文本类型的键值对,所以在prop节点内写上文本即可。

       <property name="pros">
            <props>
                <prop key="StringKey">StringValue</prop>
            </props>
        </property>
      二 P命名空间

    spring IOC容器在创建对象的时候,很多场景需要注入依赖,在使用属性方式注入时,编写property节点会很常用,为了简化配置文件关于property的写法,spring提供了P名称空间:   

xmlns:p="http://www.springframework.org/schema/p"
在编写bean节点的时候,可以使用 p:属性变量=值     
        <!--String类型注入-->
        <bean id="user" class="yzr.entity.UserBean" p:name="StringValue"></bean>
        <!--Bean对象注入-->
	<bean id="user" class="yzr.entity.UserBean" p:myBean-ref="BeanId"></bean>
      三  spring注解

     使用注解的方式来简化使用配置文件方式创建对象的过程:

           @Repository 在持久层使用     (dao)
           @Service    在业务逻辑层使用 (service)
           @Controller 在控制层使用     (action)

           @Component  把对象加入IOC容器,都可以使用这个注解 (通用)

           @Resource   注入属性值: 从容器中找指定名称的对象,如果没有指定名称,用修饰的成员变量名称!

     Dao:

package yzr.dao;

import org.springframework.stereotype.Repository;

@Repository
public class UserDao {
	public void run(){
		System.out.println("UserDao执行Run;");
	}
}
     Service:

package yzr.service;

import javax.annotation.Resource;

import org.springframework.stereotype.Service;

import yzr.dao.UserDao;
@Service
public class UserService {
	@Resource
	private UserDao userDao=null;
	/*
	public void setUserDao(UserDao userdao){
		userDao=userdao;
	}
	*/
	public void run(){
		userDao.run();
		System.out.println("Service执行Run");
	}
	
	public UserService(){
		
	}
}
      Action:
        
package yzr.action;

import java.util.List;

import javax.annotation.Resource;

import org.springframework.stereotype.Controller;

import yzr.service.UserService;
@Controller
public class UserAction {
	@Resource
	private UserService userService=null;
	
	
	public String execute() throws Exception{
		userService.run();
		System.out.println("UserAction执行execute");
		//System.out.println(stringList);
		//System.out.println(beanList);
		return "success";
	}
}
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:p="http://www.springframework.org/schema/p"
	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.xsd
     	 http://www.springframework.org/schema/context
         http://www.springframework.org/schema/context/spring-context.xsd
         http://www.springframework.org/schema/aop
         http://www.springframework.org/schema/aop/spring-aop.xsd
         http://www.springframework.org/schema/tx
     	 http://www.springframework.org/schema/tx/spring-tx.xsd">
     	 
    <context:component-scan base-package="yzr"></context:component-scan>	 
	
	
	
</beans>   
测试:

package yzr.test;

import org.junit.Test;
import org.springframework.context.ApplicationContext;
import org.springframework.context.support.ClassPathXmlApplicationContext;
import org.springframework.core.io.Resource;

import yzr.action.UserAction;

public class app {
	String path="ApplicationContext.xml";
	@Test
	public void test() throws Exception{
		ClassPathXmlApplicationContext ac=new ClassPathXmlApplicationContext(path);
		System.out.println("加载配置文件完成");
		
		//UserAction action=(UserAction) ac.getBean("UserAction");
		//action.execute();
		
		UserAction action =null;
		action=ac.getBean(UserAction.class);
		action.execute();
	}
}


注意:当使用xml配置和使用注解两种方式一起使用的时候,如果当spring IOC容器在创建对象的时候匹配到两个或以上的时候会报错。

比如:在已经使用了注解的方式的前提下,然后又在配置文件中加上对UserAction的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:p="http://www.springframework.org/schema/p"
	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.xsd
     	 http://www.springframework.org/schema/context
         http://www.springframework.org/schema/context/spring-context.xsd
         http://www.springframework.org/schema/aop
         http://www.springframework.org/schema/aop/spring-aop.xsd
         http://www.springframework.org/schema/tx
     	 http://www.springframework.org/schema/tx/spring-tx.xsd">
     	 
    <context:component-scan base-package="yzr"></context:component-scan>	 
    <bean name="UserAction" class="yzr.action.UserAction" ></bean>
</beans>     
package yzr.test;

import org.junit.Test;
import org.springframework.context.ApplicationContext;
import org.springframework.context.support.ClassPathXmlApplicationContext;
import org.springframework.core.io.Resource;

import yzr.action.UserAction;

public class app {
	String path="ApplicationContext.xml";
	@Test
	public void test() throws Exception{
		ClassPathXmlApplicationContext ac=new ClassPathXmlApplicationContext(path);
		System.out.println("加载配置文件完成");
		
		//UserAction action=(UserAction) ac.getBean("UserAction");
		//action.execute();
		
		UserAction action =null;
		action=ac.getBean(UserAction.class);
		action.execute();
	}
}

当getBean(UserAction.class)时会报错,报错信息为:

org.springframework.beans.factory.NoUniqueBeanDefinitionException: No qualifying bean of type [yzr.action.UserAction] is defined: expected single matching bean but found 2: userAction,UserAction

at org.springframework.beans.factory.support.DefaultListableBeanFactory.getBean(DefaultListableBeanFactory.java:289)
at org.springframework.context.support.AbstractApplicationContext.getBean(AbstractApplicationContext.java:1125)
at yzr.test.app.test(app.java:21)
at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:39)
at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:25)
at java.lang.reflect.Method.invoke(Method.java:597)
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.runNotIgnored(BlockJUnit4ClassRunner.java:79)
at org.junit.runners.BlockJUnit4ClassRunner.runChild(BlockJUnit4ClassRunner.java:71)
at org.junit.runners.BlockJUnit4ClassRunner.runChild(BlockJUnit4ClassRunner.java:49)
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.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)


因为使用注解的方式spring会自动创建一个UserAction对象,而在此时我们又手动在配置文件下又加上了一个UserAction类型的bean,所以使用getBean(UserAction.class)时spring容器创建对象时会找到两个UserAction。需要去掉其中一个才对。

所以,xml配置模式和注解在不冲突的条件下可以一起使用,但如果存在重复的时候spring会报错。





  • 2
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值