文章目录
【向一个类中传递数据的方式?①普通方法、②构造方法】
【依赖注入描述了容器中建立bean与bean之间依赖关系的过程,如果bean运行需要的是数字或字符串?①引用类型、②简单类型(基本数据类型与String)】
普通方法(setter注入):
使用setter注入、<property>标签、ref属性
setter注入——1.引用类型
-
在bean中定义引用类型属性并提供可访问的
set方法
(第一期spring举例过,此处实例省略dao层和接口)public class UserServiceImpl implements UserDao { @Setter private UserDao userDao; //一个方法 public int addNewUser(User user) { return userDao.addNewUser(user); } }
-
在配置文件中使用property标签注入ref属性引用类型对象
<bean id="userDao" class="com.jules.dao.impl.UserDaoImpl"></bean> <bean id="userService" class="com.jules.service.impl.UserServiceImpl"> <property name="userDao" ref="userDao"/> </bean>
【如果不止一个引用类型,多个private UserDao userDao;,只需要在配置处配置bean,并添加<property >标签注入使用即可】
setter注入——2.简单类型(基本数据类型与String)
使用setter注入、<property>标签、value属性注入值
-
一个HelloWorld类中写一个String类型对象,提供可访问的
set方法
public class HelloWorld { @Setter private String message; public void show(){ System.out.println("打印的信息"+message); } }
-
配置:使用
property
标签、value
属性注入值<!--实例化HelloWorld类型--> <bean id="helloWorld" class="com.hz.test.HelloWorld"> <property name="message" value="辣椒面撒多了的烤串"/> </bean>
-
测试
public class main01 { public static void main(String[] args) { //使用ClassPathXmlApplicationContext读取配置文件 ApplicationContext context = new ClassPathXmlApplicationContext("applicationContext.xml"); //使用getBean("bean中ID属性值")获取对象 HelloWorld helloWorld = (HelloWorld) context.getBean("helloWorld"); helloWorld.show(); } } //控制台打印:辣椒面撒多了的烤串
构造方法(构造器注入):
使用构造器注入、<constructor-arg>标签、ref属性
示例准备:
//dao接口
public interface UserDao {
public int addNewUser(User user);
}
//dao实现
public class UserDaoImpl implements UserDao {
public int addNewUser(User user) {
System.out.println("新添加一个对象~~~");
return 0;
}
}
//service接口:
public interface UserService {
public int addNewUser(User user);
}
构造器注入——引用类型
-
在bean中定义引用类型属性并提供可访问的
构造
方法//service实现 //@AllArgsConstructor //有参构造函数 @NoArgsConstructor //无参构造函数 public class UserServiceImpl implements UserService { private UserDao userDao; //有参构造,上面注解的形式或者↓ public UserServiceImpl(UserDao userDao1111) { this.userDao = userDao; } public int addNewUser(User user) { return userDao.addNewUser(user); } }
-
配置中使用
constructor-arg
标签ref属性
<bean id="userDao" class="com.jules.dao.impl.UserDaoImpl"></bean> <bean id="userService" class="com.jules.service.impl.UserServiceImpl"> <!--构造方法注入--> //注意代码:这样写name中的值与构造方法的形参"userDao1111"对应,名称耦合 //<constructor-arg name="userDao1111" ref="userDao" /> <constructor-arg> <ref bean="userDao"></ref> </constructor-arg> </bean>
构造器注入——普通类型
-
一个String类型、一个int类型,并提供可访问的
构造
方法public class HelloWorld { private String message; private int num; public HelloWorld (String message, int num) { this.message = message; this.num = num; } public void show(){ System.out.println("打印的信息"+message+"----"+num+"条"); } }
-
配置:使用
constructor-arg
标签、value
属性注入值<!--实例化HelloWorld类型--> <bean id="helloWorld" class="com.hz.test.HelloWorld"> <!--形式1:name的值与形参名称一致--> <constructor-arg name="message" value="辣椒面撒多了的烤串"/> <constructor-arg name="num" value="10"/> </bean>
<!--实例化HelloWorld类型--> <bean id="helloWorld" class="com.hz.test.HelloWorld"> <!--形式2:type解决形参名称耦合--> <constructor-arg type="java.lang.Sring" value="辣椒面撒多了的烤串"/> <constructor-arg type="int" value="10"/> </bean>
<!--实例化HelloWorld类型--> <bean id="helloWorld" class="com.hz.test.HelloWorld"> <!--形式3:index解决参数类型重复类型--> <constructor-arg index="0" value="辣椒面撒多了的烤串"/> <constructor-arg index="1" value="10"/> </bean>
【===========================三种形式有利有弊选择使用========================】
依赖注入方式选择
- 1.强制依赖使用构造器进行,使用setter注入有概率不进行注入导致null对象出现
- 2.可选依赖使用setter注入进行,灵活性强
- Spring框架倡导使用构造器,第三方框架内部大多数采用构造器注入的形式进行数据初始化,相对严谨
- 4.如果有必要可以两者同时使用,使用构造器注入完成强制依赖的注入,使用setter注入完成可选依赖的注入
- 5.实际开发过程中还要根据实际情况分析,如果受控对象没有提供setter方法就必须使用构造器注入
6.自己开发的模块推荐使用setter注入
依赖自动装配
- 概念:IoC容器根据bean所依赖的资源在容器中自动查找并注入到bean中的过程称为自动装配
- 自动装配方式:
- 按类型:byType,(常用)
类型匹配必须唯一
- 按名称:byName(不推荐)
- 按构造方法:constructor
- 不启用自动装配:no
- 按类型:byType,(常用)
按类型:
//service实现
public class UserServiceImpl implements UserDao {
private UserDao userDao;
//ser方法必须有
public void ;setUserDao(UserDao userDao) {
this,userDao = userDao
}
//一个方法
public void save() {
System.out.println("user service save……");
userDao.save();
}
}
<bean id="userDao" class="com.jules.dao.impl.UserDaoImpl"></bean>
//按类型自动装配
<bean id="userService" class="com.jules.service.impl.UserServiceImpl" autowire="byType"/>
注意:
- 按类型装配,没有对应的注入,报错:
- 多个bean的注入:com.jules.dao.impl.UserDaoImpl对应的bean不唯一
按名称:
//service实现
public class UserServiceImpl implements UserDao {
private UserDao userDao;
//ser方法必须有
public void setUserDao(UserDao userDao) {
this,userDao = userDao
}
//一个方法
public void save() {
System.out.println("user service save……");
userDao.save();
}
}
//此时id与private UserDao userDao相对应
<bean id="userDao" class="com.jules.dao.impl.UserDaoImpl"></bean>
<bean id="userDao2" class="com.jules.dao.impl.UserDaoImpl"></bean> <!--注入不了-->
//按名称自动装配
<bean id="userService" class="com.jules.service.impl.UserServiceImpl" autowire="byName"/>
【注意:倘若同一个引用使用不同的bean,只会匹配拥有的bean;一般都只会对应一个实现类,< bean >中的id可以省略】
依赖自动装配特征
- 自动装配用于引用类型依赖注入,不能对简单类型进行操作
- 使用按类型装配时( byType )必须保障容器中相同类型的bean唯一,推荐使用
- 使用按名称装配时( byName )必须保障容器中具有指定名称的bean,因变量名与配置耦合,不推荐使用
- 自动装配优先级低于setter注入与构造器注入,同时出现时自动装配配置失效
使用p命名空间注入属性值
- p命名空间的特点:使用属性而不是子元素的形式配置Bean的属性,从而简化了配置代码
对于直接量(基本数据类型、字符串)属性:p:属性名=“属性值” 对于引用Bean的属性:p:属性名-ref="Bean的id"
- 使用前要现在Spring配置中引入p命名空间
xmlns:p="http://www.springframework.org/schema/p"
- 使用p命名空间注入属性值
<!-- p命名空间注入--> <bean id="zhangGaSay" class="service.Person" p:who="张嘎" p:say="三天不打小鬼子,手都痒痒!" /> <bean id="RodSay" class="service.Person" p:who="Rod" p:say="世界上有10种人,认识二进制的和不认识二进制的。" /> <!--定义UserDao对象,并指定id为userDao--> <bean id="userDao" class="dao.impl.UserDaoImpl" /> <!--定义UserService对象,并指定id为userService--> <bean id="userService" class="service.impl.UserServiceImpl" p:dao-ref="userDao"/>
- 完整范例:
//dao接口
public interface UserDao {
public int addNewUser(User user);
}
//daos实现
public class UserDaoImpl implements UserDao {
public int addNewUser(User user) {
System.out.println("新添加一个对象~~~"+user.getUserName());
return 0;
}
}
//service接口
public interface UserService {
public int addNewUser(User user);
}
//service实现
public class UserServiceImpl implements UserService {
//set方法
@Setter
private UserDao userDao;
@Setter
private String uname;
@Setter
private String ucode;
public int addNewUser(User user) {
user.setUserName(uname);
user.setUserCode(ucode);
return userDao.addNewUser(user);
}
}
<!-- applicationContext.xml -->
<?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"
xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans.xsd">
<bean id="userDao" class="com.jules.dao.impl.UserDaoImpl"></bean>
<bean id="userService" class="com.jules.service.impl.UserServiceImpl"
p:uname="张三"
p:ucode="1001"
p:userDao-ref="userDao">
</bean>
</beans>
public class UserServiceImplTest {
@Test
public void addNewUser() {
//使用ClassPathXmlApplicationContext读取配置文件
ApplicationContext context = new ClassPathXmlApplicationContext("applicationContext.xml");
//使用getBean("bean中ID属性值")获取对象
UserService userService = (UserService) context.getBean("userService");
userService.addNewUser(new User());
}
}
//控制台输出:新添加一个对象~~~张三
注入不同数据类型(集合、数组、set、Map、Properties类型)
直接放代码
@Setter
public class EntityTest {
private List<String> list; // List类型
private String[] array; // 数组类型
private Set<String> set; // Set类型
private Map<String, String> map; // Map类型
private Properties props; // Properties类型
}
<!--注入:此处所有的name都是TestEntity中的属性-->
<bean id="entityTest" class="com.jules.entity.EntityTest">
<!--注入List类型-->
<property name="list">
<list>
<value>注入</value>
<value>List</value>
<value>类型</value>
</list>
</property>
<!--注入数组类型-->
<property name="array">
<list>
<value>注入</value>
<value>Array数组</value>
<value>类型</value>
</list>
</property>
<!--set注入-->
<property name="set">
<set>
<value>Jules</value>
<value>朱尔斯</value>
</set>
</property>
<!--map注入-->
<property name="map">
<map>
<entry>
<key><value>5555</value></key>
<value>朱尔斯</value>
</entry>
<entry>
<key><value>6666</value></key>
<value>Jules</value>
</entry>
</map>
</property>
<!-- 另一种形式
<property name="map">
<map>
<entry key="jules" value="22">
<entry key="xxxx" value="22">
<entry key="yyyy" value="22">
</map>
</property>
-->
<!--Properties类型注入-->
<property name="props">
<props>
<prop key="url">lochost:xxxx/xx/x/x</prop>
<prop key="driver">aaaaa</prop>
<prop key="username">root</prop>
<prop key="password">root</prop>
</props>
</property>
</bean>