一.依赖注入
1.通过属性标签property注入
property标签
属性: name:属性名 value:属性值 ref:依赖的对象id
测试代码:
public class Drink {
private String name;
private String sugar;
private float price;
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public String getSugar() {
return sugar;
}
public void setSugar(String sugar) {
this.sugar = sugar;
}
public float getPrice() {
return price;
}
public void setPrice(float price) {
this.price = price;
}
public Drink() {
System.out.println("创建一杯饮料");
}
}
<bean id="drink_01" class="com.test.pojo.Drink" >
<property name="name" value="西瓜汁" />
<property name="price" value="18" />
<property name="sugar" value="半糖" />
</bean>
2.通过构造函数注入
constructor-arg 标签
属性: name:构造函数的参数名
value:传进去的值
ref:参数依赖的对象
index:参数类型和参数个数都相同,但顺序不同的时候,可以用index来设置顺序 从0开始
type: 参数个数相同,参数名也相同,但类型不同 ,可以用type来设置类型
测试代码:
Drink类中添加构造函数:
package com.test.pojo;
public class Drink {
private String name;
private String sugar;
private float price;
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public String getSugar() {
return sugar;
}
public void setSugar(String sugar) {
this.sugar = sugar;
}
public float getPrice() {
return price;
}
public void setPrice(float price) {
this.price = price;
}
public Drink() {
System.out.println("创建一杯饮料");
}
public Drink(String name) {
this.name = name;
}
public Drink(String name, String sugar) {
this.name = name;
this.sugar = sugar;
}
public Drink(String name, float sugar) {
this.name = name;
this.price = sugar;
}
public Drink(float sugar,String name) {
this.name = name;
this.price = sugar;
}
@Override
public String toString() {
return "Drink{" +
"name='" + name + '\'' +
", sugar='" + sugar + '\'' +
", price=" + price +
'}';
}
}
配置文件中调用不同构造函数测试:
<bean id="drink_02" class="com.test.pojo.Drink">
<constructor-arg name="name" value="苹果汁" />
</bean>
<!--
构造函数的参数个数相同 参数类型也相同 但顺序不同 需要用index来指定参数的顺序
index 指的是参数的顺序
-->
<!-- 如果构造函数的参数个数相同 参数类型不同 则需要指定参数类型
基本类型 直接用基本类型
-->
<bean id="drink_02" class="com.test.pojo.Drink" >
<constructor-arg name="name" value="奶茶" />
</bean>
<bean id="drink_03" class="com.test.pojo.Drink" >
<constructor-arg name="name" value="珍珠奶茶" index="0" />
<constructor-arg name="sugar" value="13" type="float" index="1" />
</bean>
3.p空间注入
1)引入p空间
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"
xmlns:context="http://www.springframework.org/schema/context"
xmlns:p="http://www.springframework.org/schema/p" //加在xmlns属性中
xsi:schemaLocation="http://www.springframework.org/schema/beans
2)使用
p:属性名=属性值
<bean id="drink_01" class="com.test.pojo.Drink" p:name="珍珠奶茶"
p:price="28" p:sugar="半糖" />
4.复杂类型注入
对象 ref
数组
<array>
<value>/<ref>
</array>
list
<list>
<value>/<ref>
</list>
map
<map>
<entry key="" value=""/value-ref=""></entry>
</map>
properties
<props>
<prop key="">value</prop>
</props>
测试代码:
1)定义一个类,属性是各种复杂类型
public class AA {
private int[] arr;
private Drink[] drinkArr;
private List<String> stringList;
private List<Drink> drinkList;
private Map<String,Drink> map;
private Properties properties;
。。。
set和get方法
--
}
- 注入
<bean id="drink_01" class="com.test.pojo.Drink" />
<bean id="drink_02" class="com.test.pojo.Drink" />
<bean id="aa" class="com.test.pojo.AA">
<property name="arr">
<array>
<value>1</value>
<value>2</value>
<value>3</value>
</array>
</property>
<property name="drinkArr">
<array>
<ref bean="drink_01" />
<ref bean="drink_02" />
</array>
</property>
<property name="stringList">
<list>
<value>tom</value>
<value>jack</value>
<value>tony</value>
</list>
</property>
<property name="drinkList">
<list>
<ref bean="drink_01" />
<ref bean="drink_02" />
</list>
</property>
<property name="map">
<map>
<entry key="first" value-ref="drink_01" />
<entry key="second" value-ref="drink_02" />
</map>
</property>
<property name="properties">
<props>
<prop key="driver" >com.mysql.jdbc.Driver</prop>
<prop key="url" >jdbc:mysql://localhost:3306/taobao</prop>
</props>
</property>
</bean>
5.spel 表达式语言 注入
比如如果只是引入对象中的某个属性 可以 用#{}
<bean id="outSeller_05" class="com.test.pojo.OutSeller" p:type="饿了么"
p:drink-ref="drink_05" />
<bean id="outSeller_06" class="com.test.pojo.OutSeller">
<property name="type" value="#{outSeller_05.type}" />
<property name="drink" ref="drink_05" />
</bean>
二.SPEL
spel:spring 表达式语言 ,Spring Expression Language(缩写为SpEL)是一种强大的表达式语言。在Spring产品组合中,它是表达式计算的基础。它支持在运行时查询和操作对象图,它可以与基于XML和基于注解的Spring配置还有bean定义一起使用。由于它能够在运行时动态分配值,因此可以为我们节省大量Java代码
需要的jar包
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-expression</artifactId>
<version>4.3.18.RELEASE</version>
</dependency>
1.定义测试案例
自定义类: function类
package com.test.spel;
import com.test.pojo.Drink;
import java.util.ArrayList;
import java.util.List;
public class TestSpel {
//成员方法 先创建对象 再调用对象中的方法
// <bean id="testSpel" class="com.test.spel.TestSpel"/>
//#{testSpel.getDrinkList()}
public List<Drink> getDrinkList()
{
List<Drink> list=new ArrayList<Drink>();
list.add(new Drink("奶茶"));
list.add(new Drink("橙汁"));
return list;
}
//静态方法 可以直接用类名访问 # {T(com.test.spel.TestSpel).getDrinkList2()}
public static List<Drink> getDrinkList2()
{
List<Drink> list=new ArrayList<Drink>();
list.add(new Drink("奶茶2"));
list.add(new Drink("橙汁2"));
return list;
}
}
2.在 spring的配置文件中的使用
访问成员属性
#{对象.属性名}
访问静态方法
#{T(包名.类名).方法名([参数])}
访问成员方法
#{对象.方法名()}
<bean id="testSpel" class="com.test.spel.TestSpel"/>
<!-- 访问成员方法 -->
<bean id="aa" class="com.test.pojo.AA">
<property name="num" value="#{3*4}" />
<property name="drinkList" value="#{testSpel.getDrinkList()}" />
</bean>
<!-- 访问静态方法 -->
<bean id="aa2" class="com.test.pojo.AA">
<property name="drinkList" value="#{T(com.test.spel.TestSpel).getDrinkList2()}" />
</bean>
三.注解方式
使用注解的方式完成IOC
1.配置注解扫描
<?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.xsd http://www.springframework.org/schema/context http://www.springframework.org/schema/context/spring-context.xsd">
<!-- 开启注解扫描
扫描com.test包以及所有子包中的文件
-->
<context:component-scan
base-package="com.test" />
</beans>
2.常用的注解
2.1用来创建对象的注解
@Component
创建一个对象(组件)
@Service
创建service层对象
@Controller
创建控制层对象
//默认会创建一个DrinkService的对象 对象的名字为drinkService (类名的首字母小写)
@Service
//也可以设置自己制定的对象名
@Service("自己制定的对象名")
public class DrinkService implements IDrinkService {
}
2.2用来注入的注解
2.2.1注入对象的方式1
@Autowired
根据类型自动注入
@Qualifier(“对象名”)
如果满足自动注入的对象有多个,可以通过@Qualifier()设置具体的对象名
//自动注入
@Autowired
//指定注入的对象(如果满足注入对象有多个的时候)
@Qualifier("oracleDrinkDao")
private IDrinkDao drinkDao;
public IDrinkDao getDrinkDao() {
return drinkDao;
}
//也可以在set方法上设置自动注入
public void setDrinkDao(IDrinkDao drinkDao) {
this.drinkDao = drinkDao;
}
2.2.2注入对象的方式2
@Resource(name=“对象名”)
根据对象名注入,作用相当于@Autowired+@Qualifier(“对象名”)
//自动注入方式2
@Resource(name="oracleDrinkDao")
private IDrinkDao drinkDao;
public IDrinkDao getDrinkDao() {
return drinkDao;
}
public void setDrinkDao(IDrinkDao drinkDao) {
this.drinkDao = drinkDao;
}
2.2.3注入普通值
**@Value(“数值”)**相当于 @Value(value=“数值”)
@Component
public class Drink {
@Value("橙汁")
private String name;
@Value("半糖")
private String sugar;
@Value("18")
private float price;
2.3其它注解
@Scope
设置对象的作用域,默认是单例,可以设置为多例模式@Scope(scopeName=“prototype”)
@Lazy
设置是否懒加载,默认是非懒加载,设置 @Lazy代表懒加载,前提是单例模式
//可以设置对象作用域
//默认是单例
//可以设置为多例
//@Scope(scopeName ="prototype" )
//设置是否是懒加载 默认是false 前提是单例
@Lazy
@Component
public class Drink {
@Value("橙汁")
private String name;
}