Spring bean的几种装配方式
对象的个数,对象创建的时机
一 bean的装配(xml方式1)
1.对象创建:单例、多例
scope="singleton" 默认值 单例
scope="prototype",多例
2.什么时候创建
scope="prototype" 在使用到对象时,才创建对象
scope="singleton" 在启动(容器初始化之前),创建bean,整个应用只有一个对象
3.是否延迟加载
lazy-init="default" 默认为false不延迟,启动时创建
lazy-init="true" 延迟,启动时不创建,使用时创建
4.创建对象之后的初始化与销毁
init-method ="对象自定义的init方法名称"
destroy-method="对象自定义的destroy方法名称"
在applicationContext.xml文件中
(此处还没有用到p-namespace,后面会介绍。介绍p-namespace之前,applicationContext的头部都如下所示,在使用p-namespace是后增加一个xmlns:p="http://www.springframework.org/schema/p")
<beans xmlns="http://www.springframework.org/schema/beans"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://www.springframework.org/schema/beans
http://www.springframework.org/schema/beans/spring-beans-3.2.xsd>
<!--1.无参构造--> <!--单例模式,默认的设置,在加载容器之前bean中的对象就会被创建--> <bean id="user1",class="XXX.User" scope="singleton"> <!--多例模式,在加载容器之后,bean中的对象才会被创建,不管是否调用applictionContext.getBean()--> <bean id="user2",class="XXX.User" scope="prototype"> <!--多例模式延迟加载,在调用applictionContext.getBean()之后,对象才会被创建--> <bean id="user3",class="XXX.User" scope="prototype" lazy-init="true">
</beans>
class User{ private int id; private String name; public User(){ } public User(int id,String name){ this.id=id; this.name=name; } public void initUser(){ System.out.println("初始化"); } public void destroyUser(){ System.out.println("对象销毁"); } //get and set //toString() }
class UserFactory{ public User getInstance(){ return new User(); } public static User getStaticInstance(){ return new User(); } }
二、bean的装配(xml方式2)
Spring IOC容器
Spring IOC容器:是Spring的核心内容
作用:创建对象,处理对象的依赖关系
IOC容器创建对象
几种方式:
1.调用无参构造
2.带参数构造
3.工厂创建对象
工厂类:静态方法创建对象
非静态方法创建对象
<!--1.无参构造--> <!--单例模式,默认的设置,在加载容器之前bean中的对象就会被创建--> <bean id="user1",class="XXX.User" scope="singleton"> <!--多例模式,在加载容器之后,bean中的对象才会被创建,不管是否调用applictionContext.getBean()--> <bean id="user2",class="XXX.User" scope="prototype"> <!--多例模式延迟加载,在调用applictionContext.getBean()之后,对象才会被创建--> <bean id="user3",class="XXX.User" scope="prototype" lazy-init="true"> <!--2.参数构造--> <bean id="str" calss="java.lang.String"> <constructor-arg value="Tom" ></constructor-arg> </bean> <bean id="user4" calss="java.lang.String"> <constructor-arg index="0" value="998" type="int"></constructor-arg> <constructor-arg index="1" ref="s"></constructor-arg> </bean> <!--3.工厂模式创建对象 --> <!--工厂模式创建对象,使用非静态方法--> <bean id="factory",class="XXX.UserFactory" > <bean id="user5",factory-bean="factory" factory-method="getInstance"> <!--工厂模式创建对象,使用静态方法--> <bean id="user6",calss="XXX.UserFactory" factory-method="getStaticInstance">
三、bean的装配(xml方式3)
对象依赖关系
DI,依赖注入
1.通过构造
2.通过set方法对属性注入
3.p名称空间
4.自动装配
<!--1.参数构造--> <bean id="user1" calss="xxx.User"> <constructor-arg index="0" value="998" type="int"></constructor-arg> <constructor-arg index="1" value="Tom" type="java.lang.String"></constructor-arg> </bean> <bean id="str" calss="java.lang.String"> <constructor-arg value="Tom" ></constructor-arg> </bean> <bean id="user2" calss="xxx.User"> <constructor-arg index="0" value="998" type="int"></constructor-arg> <constructor-arg index="1" ref="s"></constructor-arg> </bean> <!--2.通过set方法对属性注入--> <bean id="user3" calss="xxx.User"> <property name="id" value="998"></property> <property name="name" value="Tom "></property> </bean>
Controller/Service/Dao开发
java类
class Test{ public static void main(String[] args){ ApplicationContext applicationContext=new ClassPathXmlApplicationContext("applicationContext.xml");//注意文件的路径 UserAction userAction=(UserAction) applicationContext.getBean("userAction"); userAction.adddUser(); } }
//UserController.java class UserController{ UserService userService; private void setUserService(UserService userService){ this.userService=userService; } private void addUser(){ userService.save(); } }
//UserService.java class UserService { private UserDao userDao; private void setUserDao (UserDao userDao){ this.userDao=userDao; } private void save(){ userDao.save(); } }
//UserDao .java class UserDao { public void save(){ System.out.println("正在保存"); } }
注入controller、service、dao方式1
applicationContext.xml文件
<!-- Controller --> <bean id="userController" calss="xxx.UserController"> <property name="userService" ref="userService"></property> </bean> <!-- Service --> <bean id="userService " calss="xxx.UserService r"> <property name="userDao" ref="userDao"></property> </bean> <!-- Dao --> <bean id="userDao" calss="xxx.UserDao"> </bean>
注入controller、service、dao方式2
applicationContext.xml文件
<!-- Controller --> <bean id="userController2" calss="xxx.UserController"> <property name="userService" > <bean calss="xxx.UserService></bean> <property name="userDao" > <bean calss="xxx.UserDao></bean> </property> </property> </bean>
开始介绍p-namespace
<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" xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans-3.2.xsd> <!--以前的方式--> <!-- <bean id="user" class="xxx.User"> <property name="id" value ="998"></property> </bean> --> <!--使用p-namespace的方式--> <bean id="user" class="xxx.User" p:id="998" p:name="Tom"></bean> <bean id="userDao" class="xxx.UserDao" ></bean> <bean id="userService" class="xxx.UserService" p:userDao-ref="userDao"></bean> <bean id="userController" class="xxx.UserController" p:userService-ref="userService"></bean> </beans>
自动装配
a.根据名称、类型自动装配
autowire="byName";自动ioc容器中去找与属性名同名的对象,自动注入
autowire="byType" IOC容器中只有一个该类型的对象,按照类型匹配,名字与属性名不同也可以匹配。
但是注意这种情况,有两个bean实现同一个接口,自动按照类型装配会找不到到底是哪一个,就会报错
b.定义全局
<beans
......
default-autowire="byName">
......
</beans>
<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" xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans-3.2.xsd> <!--自动装配 autowire="byName" autowire="byType"--> <!--根据名称自动匹配autowire="byName";自动ioc容器中去找与属性名同名的对象,自动注入--> <bean id="user" class="xxx.User" p:id="998" p:name="Tom"></bean> <bean id="userDao" class="xxx.UserDao" ></bean> <bean id="userService" class="xxx.UserService" autowire="byName"></bean> <bean id="userController" class="xxx.UserController" autowire="byType"></bean> </beans>
<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" xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans-3.2.xsd default-autowire="byName"> <!--所有默认根据名称自动匹配default-autowire="byName"--> <bean id="user" class="xxx.User" p:id="998" p:name="Tom"></bean> <bean id="userDao" class="xxx.UserDao" ></bean> <bean id="userService" class="xxx.UserService"></bean> <bean id="userController" class="xxx.UserController"></bean> </beans>
四、bean的装配(注解)
可以简化Sping IOC容器的配置
在applicationcontext.xml文件,必须引入xmlns=context="http://www.springframework.org/schema/context"
在xsi=schemaLocation需要说明一下
<!--引入context名称空间-->
<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" xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans-3.2.xsd http://www.springframework.org/schema/context http://www.springframework.org/schema/context/spring-context.xsd>
使用步骤:(需要aop包)
1.先引入context名称空间
2.开启注解扫描
<context:component-scan base -pase-package="xxx.xxx.xxx"></context:cpmponent-scan>
/** *等价于在xml文件中定义<bean id="userDao" calss="xxx.UserDao"> */ @Component("userDao") public class UserDao{ public void save(){ System.out.println("正在保存"); } }
@Component("userService")//把一个对象加入到IOC容器中 public class userService{ //@Resource(name="userDao"),其中的name就是在UserDao.java中@Component("userDao") /*等价于 <bean id="userService " calss="xxx.UserService r"> <property name="userDao" ref="userDao"></property> </bean> */ @Resource(name="userDao")//属性的注入,在字段上
private UserDao userDao;
public void setUserDao(UserDao userDao){
this.userDao=userDao } public void save(){ userDao.save(); } }
@Component("userController") class UserController{ @Resource(name="userService") UserService userService; private void setUserService(UserService userService){ this.userService=userService; } private void addUser(){ userService.save(); } }
使用注解:
把对象加入IOC容器 @Component
处理对象依赖关系@Resource
直接使用@Component //在IOC容器中加入的对象的名称与类名相同,第一个字母小写,eg:UserController的名字默认为userController
直接使用@Resource //根据类型进行查找,如果找到,直接注入
注意 直接使用@Component不知道组件到底是哪个层的,所以Spring还提供了其他类型的注解
持久层用@Repository UserDao
控制层@Controller UserController
业务逻辑层@Service UserService
总结:
使用注解,可以简化配置,且可把对象加入IOC容器,处理依赖关系
使用注解可以和xml配置文件结合使用