创建对象与对象依赖关系

Java框架

浏览数:91

2019-6-29

AD:资源代下载服务

创建对象

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配置是可以一起使用的

 

作者:一盏淡酒、醉了夕阳