Spring IOC 注入方式详解 附代码

时间:2023-03-08 22:03:46

引言

  Spring框架作为优秀的开源框架之一,深受各大Java开发者的追捧,相信对于大家来说并不陌生,Spring之所以这么流行,少不了他的两大核心技术IOC和IOP。我们这里重点讲述Spring框架的IOC技术运用,如何运用好Spring的IOC技术。

  在我们平 常的java开发中,程序员在某个类中需要依赖其它类的方法,则通常是new一个依赖类再调用类实例的方法,这种开发存在的问题是new的类实例不好统一 管理,spring提出了依赖注入的思想,即依赖类不由程序员实例化,而是通过spring容器帮我们new指定实例并且将实例注入到需要该对象的类中。 依赖注入的另一种说法是“控制反转”,通俗的理解是:平常我们new一个实例,这个实例的控制权是我们程序员,而控制反转是指new实例工作不由我们程序 员来做而是交给spring容器来做。

  在Spring容器中为一个bean配置依赖注入有三种方式:

   1) 使用属性的setter方法注入 ;

   2) 使用构造器注入;

   3) 使用Filed注入(用于注解方式)

准备工作

  在开始我们的学习之旅前,我们需要准备IOC必备的开发包。

aaarticlea/png;base64,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" alt="" />

  资源下载链接:http://download.****.net/detail/yfyzy/8912543

一.使用属性的setter方法注入

  首先要配置被注入的bean,在该bean对应的类中,应该有要注入的对象属性或者基本数据类型的属性,并且拥该属性或数据类型的set方法。

setter注入-示例:

 //我们首先定义一个UserDao的接口
interface UserDao { public void say();
} //定义一个类,并且实现我们的UserDao接口
class UserDaoImpl implements UserDao { @Override
public void say() {
System.out.println("我是UserDaoImpl类,我是实现了UserDao接口,我是通过set方法创建的。");
}
} class UserService { //注意这里定义的userDao是接口的引用。当然也可以是 UserDaoImpl userDao 。
//我们提倡用前者,面向接口编程,来降低我们代码的耦合度!!!
private UserDao userDao; public void setUserDao(UserDao userDAO) {
this.userDao = userDAO;
} public void fun() { System.out.println("我要执行真正的逻辑操作了"); //请注意,在整个过程中,我们并没有手动实例化过userDao对象,而是让Spring容器为我们实例化的
userDao.say();
}
} public class SetTest { public static void main(String[] args) {
ApplicationContext context = new ClassPathXmlApplicationContext("set.xml"); // 2、从容器中获取Bean
UserService userDao = context.getBean("userService", UserService.class); // 3、执行业务逻辑
userDao.fun();
}
}

set.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-3.0.xsd
http://www.springframework.org/schema/context
http://www.springframework.org/schema/context/spring-context-3.0.xsd"> <bean id="userService" class="UserService">
<!--依赖注入,配置当前类中相应的属性,该属性必须有对应的set方法-->
<property name="userDao" ref="userDao"></property>
</bean>
<bean id="userDao" class="UserDaoImpl"></bean> </beans>

  不知道你对上述配置文件是否了解,我们就先简单的介绍一下,<bean>代表一个java对象,id="userService" class="UserService"  ,则相当于我们平时写Java代码的UserService userService 。<property>则是为配置的对象设置属性。<property name="userDao" ref="userDao"></property> 在这个标签中 name 代表着 class="UserService"  这个类的属性,ref 则是指向已经当经定义好的bean对象。请特别留意代码中的那句注释“<!--依赖注入,配置当前类中相应的属性,该属性必须有对应的set方法-->”,否则运行时会报错。特别注意了哦!! 在这里我们的class引入的是类的路径: 包名.类型 ,例如在 在com包下有类 Test,则class = "com.Test" 。特别注意了哦。

 

工厂注入

  有时候,我们希望产生对象是通过我们写工厂方法产生,并且又希望能通过Spring来产生对象,下面我们就来看看Spring如何通过工厂来注入。

静态工厂注入

  静态工厂顾名思义,就是通过调用静态工厂的方法来获取自己需要的对象,为了让spring管理所有对象,我们不能直接通过"工程类.静态方法()"来获取对象,

而是依然通过Spring注入的形式获取。

静态工厂注入-示例:

 1 //我们首先定义一个UserDao的接口
2 interface UserDao {
3
4 public void say();
5 }
6
7 //定义一个类,并且实现我们的UserDao接口
8 class UserDaoImpl implements UserDao {
9
10 @Override
11 public void say() {
12 System.out.println("我是UserDaoImpl类,我是实现了UserDao接口,我是通过工厂的静态方法产生的");
13 }
14 }
15
16 //添加静态工厂
17 class DaoFactory {
18 //静态工厂
19 public static final UserDao getStaticFactoryDaoImpl(){
20 return new UserDaoImpl();
21 }
22 }
23
24 class UserService {
25
26 private UserDao userDao;
27
28 public void setUserDao(UserDao userDao) {
29 this.userDao = userDao;
30 }
31
32 public void fun() {
33 userDao.say();
34 }
35 }
36
37 public class FactoryStaticsTest {
38
39 public static void main(String[] args) {
40
41 ApplicationContext context = new ClassPathXmlApplicationContext("factory.statics.xml");
42
43 // 2、从容器中获取Bean
44 UserService userDao = context.getBean("userService", UserService.class);
45
46 // 3、执行业务逻辑
47 userDao.fun();
48 }
49
50 }

 factory.statics.xml配置

 1 <?xml version="1.0" encoding="UTF-8"?>
2 <beans xmlns="http://www.springframework.org/schema/beans"
3 xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:context="http://www.springframework.org/schema/context"
4 xsi:schemaLocation="
5 http://www.springframework.org/schema/beans
6 http://www.springframework.org/schema/beans/spring-beans-3.0.xsd
7 http://www.springframework.org/schema/context
8 http://www.springframework.org/schema/context/spring-context-3.0.xsd">
9
10 <bean id="userService" class="factory.statics.UserService">
11 <!--依赖注入,配置当前类中相应的属性,该属性必须有对应的set方法-->
12 <property name="userDao" ref="userDao"></property>
13 </bean>
14 <bean id="userDao" class="factory.statics.DaoFactory"
15 factory-method="getStaticFactoryDaoImpl"></bean>
16 </beans>

实例工厂的方法注入

  实例工厂的意思是获取对象实例的方法不是静态的,所以你需要首先new工厂类,再调用普通的实例方法。(PS: 先有工厂对象,在通过工厂的对象来产生我们的业务逻辑对象。)

实例工厂注入-示例:

 1 //我们首先定义一个UserDao的接口
2 interface UserDao {
3
4 public void say();
5 }
6
7 //定义一个类,并且实现我们的UserDao接口
8 class UserDaoImpl implements UserDao {
9 @Override
10 public void say() {
11 System.out.println("我是UserDaoImpl类,我是实现了UserDao接口,我是通过工厂的实例方法产生的");
12 }
13 }
14
15 //添加工厂类
16 class DaoFactory {
17
18 //产生UserDao对象
19 public UserDao getFactoryDaoImpl(){
20 return new UserDaoImpl();
21 }
22 }
23
24 class UserService {
25
26 private UserDao userDao;
27
28 public void setUserDao(UserDao userDao) {
29 this.userDao = userDao;
30 }
31
32 public void fun() {
33 userDao.say();
34 }
35 }
36
37 public class FactoryObject {
38
39 public static void main(String[] args) {
40 ApplicationContext context = new ClassPathXmlApplicationContext("factory.object.xml");
41
42 // 2、从容器中获取Bean
43 UserService userDao = context.getBean("userService", UserService.class);
44
45 // 3、执行业务逻辑
46 userDao.fun();
47 }
48 }

factory.object.xml 配置

 1 <?xml version="1.0" encoding="UTF-8"?>
2 <beans xmlns="http://www.springframework.org/schema/beans"
3 xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:context="http://www.springframework.org/schema/context"
4 xsi:schemaLocation="
5 http://www.springframework.org/schema/beans
6 http://www.springframework.org/schema/beans/spring-beans-3.0.xsd
7 http://www.springframework.org/schema/context
8 http://www.springframework.org/schema/context/spring-context-3.0.xsd">
9
10 <bean id="userService" class="factory.object.UserService">
11 <!--依赖注入,配置当前类中相应的属性,该属性必须有对应的set方法-->
12 <property name="userDao" ref="userDao"></property>
13 </bean>
14 <bean id="daoFactory" class="factory.object.DaoFactory"></bean>
15 <bean id="userDao" factory-bean="daoFactory"
16 factory-method="getFactoryDaoImpl"> </bean>
17 </beans>

二.使用构造器注入

  使用构造器注入方式,不用为该类的属性属性设置setter方法,但是需要生成该类的相应的构造方法构造方法。

构造器注入-示例:

 //我们首先定义一个UserDao的接口
interface UserDao { public void say();
} //定义一个类,并且实现我们的UserDao接口
class UserDaoImpl implements UserDao {
@Override
public void say() {
System.out.println("我是UserDaoImpl类,我是实现了UserDao接口,我是通过构造方法创建的。");
}
} class UserService { private UserDao userDao; public UserService(UserDao userDao){
this.userDao = userDao;
} public void fun() {
userDao.say();
}
} public class ConstructorTest { public static void main(String[] args) { ApplicationContext context = new ClassPathXmlApplicationContext("construct.xml"); // 2、从容器中获取Bean
UserService userDao = context.getBean("userService", UserService.class); // 3、执行业务逻辑
userDao.fun();
} }

construct.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-3.0.xsd
http://www.springframework.org/schema/context
http://www.springframework.org/schema/context/spring-context-3.0.xsd"> <bean id="userService" class="constructor.UserService">
<!--创建构造器注入,如果主类有带参的构造方法则需添加此配置 -->
<constructor-arg index="0" ref="userDao"></constructor-arg>
</bean>
<bean name="userDao" class="constructor.UserDaoImpl"></bean>
</beans>

三.使用字段(Filed)注入(用注解方式)

  在学习注解注入方式之前,我们首先了解从spring2.5增加的新特性,这些新特性包括:

  注解驱动的依赖性注入(annotation- driven dependency injection),使用注解而非XML元数据来自动侦测classpath上的Spring组件,注解对生命周期方法的支持,一个新的web控制器模 型将请求映射到加注解的方法上,在测试框架中支持Junit4,Spring XML命名空间的新增内容,等等。

在Spring中,注入依赖对象可以采用手工装配或自动装配,在实际应用开发中建议使用手工装配,因为自动装配会产生许多未知情况,开发人员无法预见最终的装配结果。

手工装配依赖对象又分为两种方式:

1)一种是在XML文件中,通过在bean节点下配置;如上面讲到的使用属性的setter方法注入依赖对象和使用构造器方法注入依赖对象都是这种方式。

2)另一种就是在java代码中使用注解的方式进行装配,在代码中加入@Resource或者@Autowired

怎样使用注解的方式来为某个bena注入依赖对象呢?

首先,我们需要在Spring容器的配置文件applicationContext.Xml文件中配置以下信息,该信心是一个Spring配置文件的模板:

 <?xml version="1.0" encoding="UTF-8"?>

 <beans

 xmlns="http://www.springframework.org/schema/beans"

 xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"

 9 xmlns:context="http://www.springframework.org/schema/context"

 xmlns:p="http://www.springframework.org/schema/p"

 xsi:schemaLocation="http://www.springframework.org/schema/beans 

 http://www.springframework.org/schema/beans/spring-beans-2.5.xsd

17 http://www.springframework.org/schema/context
18
19 http://www.springframework.org/schema/context/spring-context-2.5.xsd "> </beans>

为了获得新的的特性  首先要引入新的context的Schema命名空间,该命名空间对注释驱动、属性文件引入、加载期织入等功能提供了便捷的配置。我们知道注释本身是不会 做任何事情的,它仅提供元数据信息。要使元数据信息真正起作用,必须让负责处理这些元数据的处理器工作起来。

注意:只有配置了红色部分的代码 才可以引入注解的命名空间,否则报错。  以上的配置隐式的注册了多个对注释进行解析的处理 器:AutowiredAnnotationBeanPostProcessor、 CommonAnnotationBeanPostProcessor、PersistenceAnnotationBeanPostProcessor 等。

其次,在配置文件中打开<context:annotation-config>节点,告诉Spring容器可以用注解的方式注入依赖对象;其在配置文件中的代码如下:

<beans>

……

<context:annotation-config></context:annotation-config>

……

</beans>

第三,在配置文件中配置bean对象,如下:

<bean id="userDao" class="annotation.manul.UserDaoImpl"></bean>
   <bean id="userService" class="annotation.manul.UserService"></bean>

注解注入-示例:

 interface UserDao {

     void say();
} class UserDaoImpl implements UserDao {
@Override
public void say() {
System.out.println("I am created by manual annotation! + UserDaoImpl");
}
}
class UserService { @Resource(name="userDao")
private UserDao userDao = null; public UserDao getUserDao() {
return userDao;
} //在该属性的set方法上添加对应的方法,也能达到相同的效果。
/*@Resource(name="userDao")
public void setUserDa(UserDao userDao) {
this.userDao = userDao;
}*/ public void fun() {
userDao.say();
}
} public class AnnotationManulTest { public static void main(String[] args) { ApplicationContext context = new ClassPathXmlApplicationContext(
"applicationContext.xml"); // 2、从容器中获取Bean UserService userDao = context.getBean("userService", UserService.class); // 3、执行业务逻辑
userDao.fun(); } }

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"
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">
<!-- 打开<context:annotation-config>节点,告诉Spring容器可以用注解的方式注入依赖对象 -->
<context:annotation-config></context:annotation-config>

14 <bean id="userDao" class="annotation.manul.UserDaoImpl"></bean>
15 <bean id="userService" class="annotation.manul.UserService"></bean> </beans>

  其中,在Java代码中可以使用@Autowired或@Resource注解方式进行Spring的依赖注入。两者的区别是:

  1)@Autowired默认按类型装配。

  2)@Resource默认按名称装配,当找不到与名称匹配的bean时,才会按类型装配。

  比如:我们用@Autowired为上面的代码UserDAO接口的实例对象进行注解,它会到Spring容器中去寻找与UserDAO对象相匹配的类型,如果找到该类型则将该类型注入到userdao字段中;

  如果用@Resource进行依赖注入,它先会根据指定的name属性去Spring容器中寻找与该名称匹配的类型,例如:@Resource(name="userDao"),如果没有找到该名称,则会按照类型去寻找,找到之后,会对字段userDao进行注入。

通常我们使用@Resource。

  使用注解注入依赖对象不用再在代码中写依赖对象的setter方法或者该类的构造方法,并且不用再配置文件中配置大量的依赖对象,使代码更加简洁,清晰,易于维护。我们可以直接对属性进行注入,也可以对setter方法,进行注入。以下两种方式都是对的:

  1)@Resource(name="userDao")

    private UserDao userDao ;

2)  @Resource(name="userDao")

  public void setUserDa(UserDao userDao)

    { this.userDao = userDao; }

  PS:在Spring IOC编程的实际开发中推荐使用注解的方式进行依赖注入。

依赖注入—自动装配

  Spring中提供了自动装配依赖对象的机制,但是在实际应用中并不推荐使用自动装配,因为自动装配会产生未知情况,开发人员无法预见最终的装配结果。自动装配是在配置文件中实现的,如下:

  <bean id="***" class="***" autowire="byType">

  只需要配置一个autowire属性即可完成自动装配,不用再配置文件中写<property>,但是在类中还是要生成依赖对象的setter方法。

  Autowire的属性值有如下几个:

  byType 按类型装配  可以根据属性类型,在容器中寻找该类型匹配的bean,如有多个,则会抛出异常,如果没有找到,则属性值为null;     

byName 按名称装配  可以根据属性的名称在容器中查询与该属性名称相同的bean,如果没有找到,则属性值为null;

   constructor 与byType方式相似,不同之处在与它应用于构造器参数,如果在容器中没有找到与构造器参数类型一致的bean,那么将抛出异常;

autodetect 通过bean类的自省机制(introspection)来决定是使用constructor还是byType的方式进行自动装配。如果发现默认的构造器,那么将使用byType的方式。

依赖注入-自动装备-示例:

 //我们首先定义一个UserDao的接口
interface UserDao { void say();
} //定义一个类,并且实现我们的UserDao接口
class UserDaoImpl implements UserDao { @Override
public void say() {
System.out.println("I am created by manual annotation! + UserDaoImpl");
}
} class UserService { private UserDao userDao = null; //这个步骤不能少,一定要设置对应的setter方法
public void setUserDao(UserDao userDao) {
this.userDao = userDao;
} public void fun() {
userDao.say();
}
} public class AnnotationManulTest { public static void main(String[] args) { ApplicationContext context = new ClassPathXmlApplicationContext("applicationContext.xml"); // 2、从容器中获取Bean
UserService userDao = context.getBean("userService", UserService.class); // 3、执行业务逻辑
userDao.fun(); } }

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"
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">
<!-- 打开<context:annotation-config>节点,告诉Spring容器可以用注解的方式注入依赖对象 --> <context:annotation-config></context:annotation-config> <bean id="userDao" class="annotation.manul.UserDaoImpl"></bean>
<bean id="userService" class="annotation.manul.UserService" autowire="byName"></bean> </beans>

自动扫描 注入(实现零配置)

  spring2.5为我们引入了组件自动扫描机制,它可以在 classPath路径底下寻找标注了@Component、@Service、@Controller、@Repository注解的类,并把这些类纳 入进spring容器中管理。它的作用和在xml文件中使用bean节点配置组件是一样的。

  也就是要spring自动扫描机制只会查找指定类路径下包含@Component、@Service、@Controller、@Repository这四种注解的类。

  要使用自动扫描机制,我们需要打开以下配置信息:

  1、引入context命名空间 需要在xml配置文件中配置以下信息: 同上先引入context 命名空间,同时

  2、在配置文件中添加context:component-scan标签

  <context:component-scan base-package="*"/>

  其中base-package为需要扫描的包(含子包)。

  注意:

  1、在使用组件扫描元素 时,AutowiredAnnotationBeanPostProcessor和CommonAnnotationBeanPostProcessor 会隐式地被包括进来。 也就是说,连个组件都会被自动检测并织入 - 所有这一切都不需要在XML中提供任何bean配置元数据。也就是说如果使用了context:component-scan标签,就可以不需要再引入 context:annotation-config标签

<context:component-scan />还允许定义过滤器将基包下的某些类纳入或排除。Spring支持以下4种类型的过滤方式:
过滤器类型 表达式范例 说明:
  1)注解 org.example.SomeAnnotation 将所有使用SomeAnnotation注解的类过滤出来 
  2)类名指定 org.example.SomeClass 过滤指定的类 
  3)正则表达式 com\.kedacom\.spring\.annotation\.web\..* 通过正则表达式过滤一些类
  4)AspectJ表达式 org.example..*Service+ 通过AspectJ表达式过滤一些类

以正则表达式为例,我列举一个应用实例:

<context:component-scan base-package="com.casheen.spring.annotation">  
  <context:exclude-filter type="regex" expression="com\.casheen\.spring\.annotation\.web\..*" />
</context:component-scan> <context:component-scan base-package="com.casheen.spring.annotation">
  <context:exclude-filter type="regex" expression="com\.casheen\.spring\.annotation\.web\..*" />
</context:component-scan>

  注意: <context:component-scan
/>配置项不但启用了对类包进行扫描以实施注释驱动Bean定义的功能,同时还启用了注释驱动自动注入的功能(即还隐式地在内部注册了
AutowiredAnnotationBeanPostProcessor和CommonAnnotationBeanPostProcessor),
因此当使用<context:component-scan />后,就可以将<context:annotation-config
/>移除了。

  需要被扫描的类添加相应的注解,注解的类型有以下几种:

  @Service用于标注业务层组件、

  @Controller用于标注控制层组件(如struts中的action)、

  @Repository用于标注数据访问组件,即DAO组件。

  而@Component泛指组件,当组件不好归类的时候,我们可以使用这个注解进行标注。 这四种注解仅仅是角色不同,但实质都一样。

  细节问题总结:

  1.当我们进行测试时,用ApplicationContext对象的getBean()方法寻找组件。在之前的配置文件中我们会用<bean>标签的id属性去定义,在使用自动扫描注解后怎样获得组建的id呢?

  在这种情况下,Spring会将被标注注解的类名,然后再将该类名的第一个字母变为小写,放到getBean()方法中。如:UserBizImpl类的组件Id就会是userBizImpl,获取时为context.getBean("userBizImpl");

  2.那么,我们在使用注解时可以自定义组件的Id吗?

  当然可以。我们需要在为相应的类添加注解时,在注解之后添加自定义的类名,例如:

  @Service("userBiz")

  public class UserBizImpl implements UserBiz {

  ……

  }

  当我们在获取该组件时,为context.getBean("userBiz);

  3.在配置文件中我们可以对组件(bean)的作用域范围进行设置,它的默认值是单例模式,那么在添加注解的情况下,我们怎样设置组件的作用域范围呢?

  我们可以直接在为类添加注解的同时,运用另一个注解@Scope("prototype")来设置,如下

  @Service("userBiz")@Scope("prototype")

  public class UserBizImpl implements UserBiz {

  ……

  }

  4.在使用注解时,为组件设置初始化和销毁方法:

  在添加注解的相应的类中,如果想初始化或销毁某个方法,我们可以直接在方法上添加注解,如下:

  @PostConstruct

  public void addItem() {

  System.out.println("初始化方法");

  }

  @PreDestroy

  public void testItem() {

  System.out.println("释放资源");

  }

  5.在使用Spring自动扫描组件后,怎样进行依赖注入?

  运用注解@Resource和@Autowired,并为依赖对象设置名称,例如:

  @Resource(name="userDao")

  private UserDAO userDao = null;

  首先它会根据名称去找Spring自动扫描的并加入到Spring容器的组件(bean),如果有相同的名称,则进行依赖注入,如果没有相同的名称。则会根据类型  区寻找组件。

  理解以上的内容后,你就可以很轻松的实现spirng零配置了 O(∩_∩)O。

自动扫描注入-示例:

 //我们首先定义一个UserDao的接口
interface UserDao { void say();
} //定义一个类,并且实现我们的UserDao接口
@Repository("userDao") //@Repository用于标注数据访问组件,即DAO组件.注解仅仅是角色不同,但实质都一样。
class UserDaoImpl implements UserDao { @Override
public void say() {
System.out.println("I am created by manual annotation! + UserDaoImpl");
}
} @Service("userService")
class UserService { private UserDao userDao = null; //这个步骤不能少,一定要设置对应的setter方法
@Resource
public void setUserDao(UserDao userDao) {
this.userDao = userDao;
} public void fun() {
userDao.say();
}
} public class AnnotationManulTest { public static void main(String[] args) { ApplicationContext context = new ClassPathXmlApplicationContext("applicationContext.xml"); // 2、从容器中获取Bean
UserService userDao = context.getBean("userService", UserService.class); // 3、执行业务逻辑
userDao.fun();
}
}

applicationContext.xm配置

 <?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-3.0.xsd
http://www.springframework.org/schema/context
http://www.springframework.org/schema/context/spring-context-3.0.xsd"> <context:component-scan base-package="annotation.manul"></context:component-scan> <!--运用自动扫描注入,就不需要下面的配置了,这个已经包含进去了-->
<!-- 打开<context:annotation-config>节点,告诉Spring容器可以用注解的方式注入依赖对象 --> </beans>

------------------------------------------------------------------------------------------------

  以上就是关于spring注入的介绍,怎么样,比较简单吧,~O(∩_∩)O~。