创建对象与对象依赖关系
创建对象
SpringIOC容器,是spring核心内容。作用: 创建对象 & 处理对象的依赖关系
IOC容器创建对象:
创建对象, 有几种方式:
1) 调用无参数构造器
在bean类中写入无参构造函数
public User() { // TODO Auto-generated constructor stub }
xml配置文件
<!-- 1、默认无参的构造器 --> <bean id="user1" class="com.gqx.create.User" ></bean>
2) 带参数构造器
相应的bean中写入
public User(int id,String name){ this.id=id; this.name=name; }
xml配置文件
<!-- 2、带构造器的参数 参数位置不可以换,除非指定了索引--> <bean id="user" class="com.gqx.create.User"> <constructor-arg value="100" index="0" type="int" ></constructor-arg> <constructor-arg val ue="gqxing" index="1" type="java.lang.String" ></constructor-arg> </bean>
或者也可以使用ref
<!-- 2.1 ref的使用 --> <!-- 定义一个字符串。值是gqxing --> <bean id="str" class="java.lang.String"> <constructor-arg value="gqxing"></constructor-arg> </bean> <bean id="user2" class="com.gqx.create.User"> <constructor-arg value="100" index="0" type="int" ></constructor-arg> <constructor-arg index="1" ref="str" type="java.lang.String" ></constructor-arg> </bean>
3) 工厂创建对象
工厂类,静态方法创建对象
工厂类,非静态方法创建对象
如下创建一个工厂类
package com.gqx.create; /** * 工厂,创建对象 * @author 郭庆兴 * */ public class ObjectFactory { //实例方法创建对象 public User getInstance(){ return new User(100,"调用实例方法"); } //静态方法创建对象 public static User getStaticInstance(){ return new User(100,"调用静态方法"); } }
在xml的beans中写入
<!-- 3、工厂类创建对象 --> <!-- #工厂类,实例方法 --> <!-- 先创建工厂 --> <bean id="factory" class="com.gqx.create.ObjectFactory"></bean> <!-- 在创建工厂,用factory的实例方法 --> <bean id="user3" factory-method="getInstance" factory-bean="factory" ></bean> <!-- 工厂类:静态方法 --> <bean id="user" class="com.gqx.create.ObjectFactory" factory-method="getStaticInstance"></bean>
对象依赖关系
Spring中,如何给对象的属性赋值? 【DI, 依赖注入】
(1)、 通过构造函数
完成bean文件后,在xml的beans中写入
<!-- **********对象属性赋值********* --> <!-- 1、通过构造函数 --> <bean id="user1" class="com.gqx.property.User"> <constructor-arg value="100"></constructor-arg> <constructor-arg value="gqxing"></constructor-arg> </bean>
(2)、 通过set方法给属性注入值
给实体类对象加入set方法,如下
public void setName(String name) { this.name = name; } public void setId(int id) { this.id = id; }
完成bean文件后,在xml的beans中写入
<!-- 2、通过set方法给属性赋值 --> <bean id="user" class="com.gqx.property.User"> <property name="id" value="101"></property> <property name="name" value="test"></property> </bean>
案例:普通MVC模式中使用此方法
a、userDao:对数据库的操作
package com.gqx.property; public class UserDao { public void save() { // TODO Auto-generated method stub System.out.println("DB:保存用户"); } }
b、UserService
package com.gqx.property; public class UserService { private UserDao userDao; //IOC:对象的创建交给spring的外部容器完成 public void setUserDao(UserDao userDao) { this.userDao = userDao; } public void save() { userDao.save(); } }
c、UserAction
package com.gqx.property; public class UserAction { //UserService:springIOC容器注入 private UserService service; public void setService(UserService service) { this.service = service; } public UserService getService() { return service; } public String execute(){ service.save(); return null; } }
d、在xml的beans中写入
<!-- 案例: action/service/dao --> <!-- dao Instance --> <bean id="userDao" class="com.gqx.property.UserDao"></bean> <!-- service Instance --> <bean id="userService" class="com.gqx.property.UserService"> <property name="userDao" ref="userDao"></property> </bean> <!-- action instance --> <bean id="userAction" class="com.gqx.property.UserAction"> <property name="service" ref="userService"></property> </bean> <!-- 也可以使用***内部bean**** --> <!-- <bean id="userAction" class="com.gqx.property.UserAction"> <property name="service"> <bean id="userService" class="com.gqx.property.UserService"> <property name="userDao"> <bean class="com.gqx.property.UserDao"></bean> </property> </bean> </property> </bean> -->
e、测试类
public class App { private ApplicationContext ac=new ClassPathXmlApplicationContext("com/gqx/property/bean.xml"); @Test public void test2() { //从容器中获取action UserAction userAction=(UserAction)ac.getBean("userAction"); userAction.execute(); } }
运行之后就会看到控制台出现如下的提示
(3)、 p名称空间(可以算得上是对上面处理的一种优化)
可以将上面的xml中的beans中的内容修改成如下
<!-- **********对象属性赋值********* --> <!-- 3、p名称空间(在spring的3.0以上版本才有效 --> <bean id="userDao" class="com.gqx.property.UserDao"></bean> <bean id="userService" class="com.gqx.property.UserService" p:userDao-ref="userDao"></bean> <bean id="userAction" class="com.gqx.property.UserAction" p:service-ref="userService"></bean> <!-- 普通的set注入 对p:属性的理解如下 <bean id="user" class="com.gqx.property.User"> <property name="name" value="gqx"></property> <property name="id" value="102"></property> </bean> --> <bean id="user" class="com.gqx.property.User" p:name="gqxing" p:id="104"></bean>
(4)、自动装配(了解)
在前面的案例基础上,可以修改xml中的beans中的内容修改成如下
<?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" 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"> <!-- **********自动装配********* --> <!-- 根据“名称”自动装配:userAction注入的属性会去IOC容器中自动查找与属性同名的对象 --> <bean id="userDao" class="com.gqx.auto.UserDao"></bean> <bean id="service" class="com.gqx.auto.UserService" autowire="byName"></bean> <bean id="userAction" class="com.gqx.auto.UserAction" autowire="byName"></bean> </beans>
或者也可以直接设置全局的autowire="byName" 如下:
<?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" 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" default-autowire="byName" > <!-- **********自动装配********* --> <!-- 根据“名称”自动装配:userAction注入的属性会去IOC容器中自动查找与属性同名的对象 --> <bean id="userDao" class="com.gqx.auto.UserDao"></bean> <bean id="service" class="com.gqx.auto.UserService" ></bean> <bean id="userAction" class="com.gqx.auto.UserAction" ></bean> </beans>
(5)、 注解
注解方式可以简化spring的IOC容器的配置!
使用注解步骤:
1)先引入context名称空间
xmlns:context="http://www.springframework.org/schema/context"
2)开启注解扫描
<context:component-scan base-package="cn.itcast.e_anno2"></context:component-scan>
<?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" 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" default-autowire="byName" > <!-- 开启扫描注解 --> <context:component-scan base-package="com.gqx.anno"></context:component-scan> </beans>
3)使用注解
通过注解的方式,把对象加入ioc容器。
还是一样按着上面的去修改案例
Dao层
package com.gqx.anno; import org.springframework.stereotype.Component; //把当前对象加入IOC容器 @Component("userDao") //相当于bean.xml 【<bean id=userDao class="..."/>】 public class UserDao { public void save() { // TODO Auto-generated method stub System.out.println("DB:保存用户!"); } }
Service层
package com.gqx.anno; import javax.annotation.Resource; import org.springframework.stereotype.Component; @Component("service") //userSrvice加入IOC容器 public class UserService { /*Resource会从IOC容器中找userDao对象,同时注入到当前字段 * 相当于 * <bean id="" class=""> * <property name="userDao" ref="userDao"/> * </bean> */ @Resource(name="userDao") private UserDao userDao; //IOC:对象的创建交给spring的外部容器完成 public void setUserDao(UserDao userDao) { this.userDao = userDao; } public void save() { userDao.save(); } }
Action
package com.gqx.anno; import javax.annotation.Resource; import org.springframework.stereotype.Component; @Component("userAction") //加入IOC容器 public class UserAction { @Resource(name="service") private UserService service; public void setService(UserService service) { this.service = service; } public UserService getService() { return service; } public String execute(){ service.save(); return null; } }
测试
public class App { private ApplicationContext ac=new ClassPathXmlApplicationContext("com/gqx/anno/bean.xml"); @Test public void test4() { //从容器中获取action UserAction userAction=(UserAction)ac.getBean("userAction"); userAction.execute(); } }
创建对象以及处理对象依赖关系,相关的注解:
@Component 指定把一个对象加入IOC容器
@Repository 作用同@Component; 在持久层使用
@Service 作用同@Component; 在业务逻辑层使用
@Controller 作用同@Component; 在控制层使用
@Resource 属性注入
如下,可以简化开发过程,去掉名称:
package com.gqx.anno_2; import org.springframework.stereotype.Component; @Component public class UserDao { public void save() { // TODO Auto-generated method stub System.out.println("DB:保存用户!"); } } package com.gqx.anno_2; import javax.annotation.Resource; import org.springframework.stereotype.Component; @Component public class UserService { @Resource private UserDao userDao; public void save() { userDao.save(); } } package com.gqx.anno_2; import javax.annotation.Resource; import org.springframework.stereotype.Component; @Component public class UserAction { @Resource private UserService service; public String execute(){ service.save(); return null; } }
同时为了开发方便,以及分清楚各个层,做了以下的简化
指定dao层 @Repository
package com.gqx.anno_3; import org.springframework.stereotype.Repository; @Repository //指定在持久层用该注解 public class UserDao { public void save() { // TODO Auto-generated method stub System.out.println("DB:保存用户!"); } }
指定service层@Service
package com.gqx.anno_3; import javax.annotation.Resource; import org.springframework.stereotype.Component; import org.springframework.stereotype.Service; @Service //指定业务逻辑层的组件 public class UserService { @Resource private UserDao userDao; public void save() { userDao.save(); } }
指定控制层@Controller
package com.gqx.anno_3; import javax.annotation.Resource; import org.springframework.stereotype.Component; import org.springframework.stereotype.Controller; @Controller //控制层的组件 public class UserAction { @Resource private UserService userService; public String execute(){ userService.save(); return null; } }
如果想要同时使用注解与XML配置,可以做如下测试,去掉UserDao的注解,然后在xml文件中加入
<!-- 注解与XML配置可以一起使用 --> <bean id="userDao" class="com.gqx.anno_4.UserDao"></bean>
运行后会发现控制台的显示如下
说明了注解与XML配置是可以一起使用的
、