JavaEE:Spring IOC和DI用法

说明:

IOC:控制反转,将对象的创建权反转给Spring,为了解耦。

DI:依赖注入,对对象的属性值进行注入赋值

通用依赖jar包:commons-logging-x.x.jar、log4j-x.x.xx.jar

spring依赖jar包:spring-core-x.x.x.RELEASE.jar、spring-context-x.x.x.RELEASE.jar、spring-beans-x.x.x.RELEASE.jar、spring-expression-x.x.x.RELEASE.jar

一、xml方式,创建对象与注入属性值:

1.属性值注入:

bean节点说明:

scope属性:
singleton:默认,单例模式
prototype:多例模式
request:用在web项目,存入request作用域
session:用在web项目,存入session作用域
globalsession:用在web项目,在porlet环境全局作用域,没有则等同于session

parent属性:指定父类,在类中不用做任何改动,能继承父类的同名属性,为父类bean设abstract=true,则父类不能被实例化

dependency-check属性:用于检查属性值是否被设置过,setter独有

init-method属性:初始化时调用配置的自定义方法(在Java类中要实现此方法)

destroy-method属性:销毁时调用配置的自定义方法(在Java类中要实现此方法)

autowire属性:指定注入时采用的方式(模式)
模式取值:
byType:按类型匹配
byName:按名称匹配
constructor:按构造方法匹配

(1)setter方式注入(对象中要有相应的set方法):

<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
	xmlns="http://www.springframework.org/schema/beans"
	xmlns:p="http://www.springframework.org/schema/p"
	xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans.xsd">

    <bean id="adress" class="com.yyh.hkw.domain.Adress">
        <property name="name" value="杨先生" /><!-- 给该类属性赋值,name是Adress中定义的变量名 -->
	</bean>

    <!-- 1.set方式注入 -->
    <bean id="user1" class="com.yyh.hkw.domain.User" init-method="onInit" destroy-method="onDestroy" scope="singleton">
		
        <!-- (1)字符串类型,给该类属性赋值,name是User中定义的变量名 -->
        <property name="name" value="杨先生" />
		
        <!-- (2)数值类型,给该类属性赋值,age是User中定义的变量名 -->
        <property name="age" value="100" />
		
        <!-- (3)对象类型,ref给对象类型赋值,adress是其他bean节点id的值 -->
        <property name="adress" ref="adress" />
		
        <!-- (4)内部类,ref给对象类型赋值,adress是其他bean节点id的值 -->
        <property name="job"> <!-- job是User中定义的变量名 -->
            <bean class="com.yyh.hkw.domain.User.Job"><!-- 内部类 -->
                <property name="name" value="技术专家" /><!-- 内部类的属性 -->
            </bean>
        </property>
		
        <!-- (5)数组类型 -->
        <property name="adressArrs">
            <list>
                <value>北京</value>
                <value>上海</value>
            </list>
        </property>
		
        <!-- (6)List类型 -->
        <property name="adressList">
            <list>
                <value>北京</value>
                <value>上海</value>
            </list>
        </property>
		
        <!-- (7)Set类型 -->
        <property name="adressSet">
            <set>
                <value>北京</value>
                <value>上海</value>
            </set>
        </property>
		
        <!-- (8)Map类型 -->
        <property name="adressMap">
            <map>
                <entry key="adress1" value="北京" />
                <entry key="adress2" value="上海" />
            </map>
        </property>

        <!-- (9)Map类型,存对象 -->
        <property name="adressObjMap">
            <map>
                <entry key-ref="adress1" value-ref="adress"/><!-- 在map中存入对象,value-ref中的adress是其他bean节点id的值 -->
            </map>
        </property>
    </bean>
</beans>

(2)构造器方式注入(代码中要有相应参数的构造方法):

<bean id="adress" class="com.yyh.hkw.domain.Adress" />

<!-- 2.构造器方式注入 -->
<bean id="user2" class="com.yyh.hkw.domain.User">
    <constructor-arg value="杨先生" /><!-- 构造方法第1个参数,value给基本类型赋值 -->
    <constructor-arg ref="adress" /><!-- 构造方法第2个参数,ref给对象类型赋值,adress是其他bean节点id的值  -->
    <!-- 其他类型和set相似,以<constructor-arg 开头 -->
</bean>

(3)p方式注入:

<beans xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
	xmlns="http://www.springframework.org/schema/beans"
	xmlns:p="http://www.springframework.org/schema/p"
	xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans.xsd">
    <bean id="adress" class="com.yyh.hkw.domain.Adress" />

    <!-- 3.p方式注入 -->
    <!-- 构造方法第2个参数,p:name给基本类型name变量赋值,p:adress-ref给对象类型变量赋值,中间的'adress'和值是一样的,值adress是其他bean节点id的值  -->
    <bean id="user3" class="com.yyh.hkw.domain.User" p:name="杨先生" p:adress-ref="adress" />

</beans>

2.用SpEL表达式给属性赋值:

说明:就是将value的值用#{}括起来。

<bean id="adress" class="com.yyh.hkw.domain.Adress" />

<!-- 用SpEL表达式给属性赋值,value的值用#{}括起来 -->
<bean id="user4" class="com.yyh.hkw.domain.User">
    <property name="name" value="#{'杨先生'}" /><!-- 字符串类型,要用单引号括起来 -->
    <property name="age" value="#{100}" /><!-- 数值类型 -->
    <property name="adress" value="#{adress}" /><!-- 对象类型,adress是其他bean节点id的值 -->
    <property name="adressName1" value="#{adress.name}" /><!-- 引用别的对象属性值,adress是其他bean节点id的值,name是Adress对象属性 -->
    <property name="adressName2" value="#{adress.getName()}" /><!-- 引用别的对象方法,adress是其他bean节点id的值,getName是Adress对象方法 -->
</bean>

3.加载配置文件,创建对象,注入属性值:

//1.自动加载applicationContext.xml配置文件, 触发applicationContext.xml中bean标签 init-method配置的方法
ApplicationContext ctx = new ClassPathXmlApplicationContext("applicationContext.xml"); 
//ApplicationContext ctx = new FileSystemXmlApplicationContext("C:\\applicationContext.xml"); //加载C盘目录下的xml配置文件
		
//2.getBean的参数"user1",为applicationContext.xml中bean标签 id值
User user1 = (User) ctx.getBean("user1");
		
//3.关闭工厂,会销毁User, 触发applicationContext.xml中bean标签 destroy-method配置的方法
((ClassPathXmlApplicationContext)ctx).close();

4.加载多个配置文件:

(1)代码方式加载:

//加载src目录下的多个xml配置文件,可传入多个
ApplicationContext ctx = new ClassPathXmlApplicationContext("applicationContext1.xml", "applicationContext2.xml");

(2)在被加载的配置文件中引入其他配置文件(可引入多个):

<beans>
    <!-- 引入其他配置文件 -->
    <import resource="applicationContext2.xml"/>
</beans>

二、注解方式,创建对象与注入属性值:

1.扫描组件(扫描类上的注解),使用IOC注解前,先开启组件扫描,在applicationContext.xml中beans节点内配置:

<!-- 使用IOC注解时,要配置组件扫描(哪个包下的类使用注解) -->
<context:component-scan base-package="com.yyh.hkw"/>

2.创建对象,在要被创建实例的类前添加注解:

(1)@Component,基本注解,标识了一个受 Spring 管理的组件:

@Component("user") //基本注解,等同于<bean id="user" class="com.yyh.hkw.domain.User">
public class User {
}

(2)@Repository,标识此类为持久层类(dao层):

@Repository("userDao") // 标识此类为持久层类,等同于<bean id="userDao" class="com.yyh.hkw.dao.impl.UserDaoImpl">
public class UserDaoImpl extends UserDao {
}

(3)@Service,标识此类为业务层类(service层):

@Service("userService") //标识此类为业务层类,等同于<bean id="userService" class="com.yyh.hkw.service.impl.UserServiceImpl">
public class UserServiceImpl implements UserService {
}

(4)@Controller,标识此类为表现层类(web层):

@Controller("userServlet") //标识此类为表现层类,等同于<bean id="userServlet" class="com.yyh.hkw.web.servlet.UserServlet">
public class UserServlet {
}

3.注入属性值:

(1)基本类型注入,使用@Value:

//没有set方法时添加到属性前
@Value("杨先生")// 属性注入,将注解添加属性前
public String name;

//或者(二选一),有set方法时添加到set方法前
@Value("杨先生")  //属性注入,添加到set方法前。
public void setName(String name) {
    this.name = name;
}

(2)对象类型注入:

方式1,按类型,使用@Autowired:

//按对象类型自动注入,Adress对象也得要加上@Component或其他3个,能被自动创建
@Autowired
public Adress adress;

方式2,按名称,@Autowired和@Qualifier配合使用:

//@Autowired和@Qualifier配合使用,按名称自动注入
@Autowired
@Qualifier(value = "adress") //adress为Adress类@Component或其他3个注解中配置的名称
public Adress adress;

方式3,按名称,使用@Resource:

// 按名称自动注入
@Resource(name = "adress") //adress为Adress类@Component或其他3个注解中配置的名称
public Adress adress;

4.初始化与销毁,使用@PostConstruct和@PreDestroy:

//初始化注解,在初始化时调用此方法
@PostConstruct
public void onInit() {
}
	
//销毁注解,在销毁时调用此方法
@PreDestroy
public void Destroy() {
}

5.作用域,使用@Scope:

@Component("user")
@Scope(scopeName = "singleton") //作用域,默认为单例singleton,其他值见上面xml方式
public class User {
}

三、xml+注解混合,创建对象与注入属性值:

1.没开扫描,让属性注入的注解可用 ,在applicationContext.xml中beans节点内配置:

<!-- xml与注解混合时,没开扫描,让属性注入的注解可用 -->
<context:annotation-config />

2.xml方式配置对象,在applicationContext.xml中beans节点内配置bean节点:

<!-- xml方式,让spring创建对象 -->
<bean id="user" class="com.yyh.hkw.domain.User" />
<bean id="adress" class="com.yyh.hkw.domain.Adress" />

3.注解方式配置属性,在类属性前加注解:

public class User {
    // 按名称自动注入,adress是applicationContext.xml中bean节点id的值
    @Resource(name = "adress")
    public Adress adress;
}

四、其他:

1.加载属性文件,在spring-config.xml的beans节点中加入:

<beans>
    ...
	<!-- 加载属性文件 -->
	<!-- <context:property-placeholder location="classpath:x.properties"/> -->
</beans>

 

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值