IOC 依赖注入
有两种方式:基于xml和注解
xml又有 构造器注入和set方法注入
SpringIOC
1.传统的new对象的方式
userDao.java
public interface UserDao {
public void getUser();
}
userDaoImpl.java
import com.peach.hong2.dao.UserDao;
public class UserDaoImpl implements UserDao {
@Override
public void getUser() {
System.out.println("dao层服务被调用");
}
}
userService.java
public interface UserService {
public void getUser();
}
UserServieceImpl.java
import com.peach.hong2.dao.UserDao;
import com.peach.hong2.dao.impl.UserDaoImpl;
import com.peach.hong2.service.UserService;
public class UserServiceImpl implements UserService {
private UserDao userDao = new UserDaoImpl();
@Override
public void getUser() {
System.out.println("service层服务被调用");
userDao.getUser();
}
}
test下面的 hong2ApplicationTests.java
private UserService userService = new UserServiceImpl();
@Test
void testUser(){
userService.getUser();
}
方式一:xml配置类
@SpringBootTest
class Hong2ApplicationTests {
//private UserService userService = new UserServiceImpl();
private UserService userService ;
@Test
void testUser(){
ApplicationContext applicationContext = new ClassPathXmlApplicationContext("bean.xml");
userService = (UserService) applicationContext.getBean("userService");
userService.getUser();
}
}
1、通过构造器
UserServiceImpl.java
public class UserServiceImpl implements UserService {
// private UserDao userDao = new UserDaoImpl();
private UserDao userDao;
//通过构造器
public UserServiceImpl(UserDao userDao) {
this.userDao = userDao;
}
@Override
public void getUser() {
System.out.println("service层服务被调用");
userDao.getUser();
}
}
bean.xml
<bean id="userService" class="com.peach.hong2.service.impl.UserServiceImpl">
<constructor-arg name="userDao" ref="userDao"></constructor-arg>
</bean>
<bean id="userDao" class="com.peach.hong2.dao.impl.UserDaoImpl"></bean>
注意: bean 的id是自己起的,后面的class是实现类的路径。
2、通过set方法和property属性值的方式注入
userServiceImpl.java
public class UserServiceImpl implements UserService {
// private UserDao userDao = new UserDaoImpl();
private UserDao aaa;
public void setAaa(UserDao hhh) {
this.aaa = hhh;
}
@Override
public void getUser() {
System.out.println("service层服务被调用");
aaa.getUser();
}
}
bean.xml
<bean id="userService" class="com.peach.hong2.service.impl.UserServiceImpl">
<!-- <constructor-arg name="userDao" ref="userDao"></constructor-arg>-->
<property name="aaa" ref="userDao"></property>
</bean>
3、普通类型的注入
1. List
给list赋值,并且输出
UserDaoImpl.java
private List<String> list;
public void setList(List<String> list) {
this.list = list;
}
@Override
public void getUser() {
System.out.println("dao层服务被调用");
for (String string:list) {
System.out.println(string);
}
}
bean.xml
<bean id="userDao" class="com.peach.hong2.dao.impl.UserDaoImpl">
<property name="list" >
<list>
<value>list1</value>
<value>list2</value>
<value>list3</value>
</list>
</property>
</bean>
2.数组
给数组赋值,并且输出
UserDaoImpl.java
private String[] arr ;
public void setArr(String[] arr) {
this.arr = arr;
}
@Override
public void getUser() {
for (String s:arr) {
System.out.println(s);
}
}
bean.xml
<bean id="userDao" class="com.peach.hong2.dao.impl.UserDaoImpl">
<property name="arr">
<array>
<value>arr1</value>
<value>arr2</value>
<value>arr3</value>
</array>
</property>
</bean>
3. set与map
<property name="set">
<set>
<value>set1</value>
<value>set2</value>
</set>
</property>
<property name="map">
<map>
<entry key="1" value="map1"/>
<entry key="2" value="map2"/>
</map>
</property>
4、测试时在主程序里写的
// 获取容器
ApplicationContext ac = new ClassPathXmlApplicationContext("springContext.xml");
// 根据beanID获取对象
// 调用前必须在springContext.xml中配置注解方式解析
IUserClientService userClientService = (IUserClientService) ac.getBean("userService");
userClientService.saveCustom();
整体代码
- 目录结构
- springContext.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"
xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans.xsd">
<bean id="userService" class="com.peach.service.impl.IUserClientServiceImpl">
<constructor-arg name="userClientDao" ref="userClientDao">
</constructor-arg>
<property name="list">
<list>
<value>list1</value>
<value>list2</value>
<value>list3</value>
</list>
</property>
<property name="arr">
<array>
<value>arr1</value>
<value>arr2</value>
<value>arr3</value>
</array>
</property>
<property name="set">
<set>
<value>set1</value>
<value>set2</value>
</set>
</property>
<property name="map">
<map>
<entry key="1" value="map1"/>
<entry key="2" value="map2"/>
</map>
</property>
</bean>
<bean id="userClientDao" class="com.peach.dao.impl.IUserClientDaoImpl"/>
</beans>
- dao层
- IUserClientDao.java
public interface IUserClientDao {
//保存客户信息
void saveCustom();
}
- IUserClientDaoImpl.java
public class IUserClientDaoImpl implements IUserClientDao {
@Override
public void saveCustom() {
System.out.println("调用持久层");
}
}
- Service层
- IUserClientService.java
public interface IUserClientService {
//保存客户信息
void saveCustom();
}
- IUserClientServiceImpl.java
public class IUserClientServiceImpl implements IUserClientService {
private IUserClientDao userClientDao; //这个是通过构造器注入的
private List<String> list;
private String[] arr;
private Set<String> set;
private Map<String,String> map;
//通过set和properties注入
public void setList(List<String> list) {
this.list = list;
}
public void setArr(String[] arr) {
this.arr = arr;
}
public void setSet(Set<String> set) {
this.set = set;
}
public void setMap(Map<String, String> map) {
this.map = map;
}
public IUserClientServiceImpl(IUserClientDaoImpl userClientDao) {
this.userClientDao = userClientDao;
}
private String name;
@Override
public void saveCustom() {
System.out.println("业务层调用持久层"+name);
userClientDao.saveCustom();
for (String str: list
) {
System.out.print(str+" ");
}
System.out.println();
for (String str:arr
) {
System.out.print(str+" ");
}
System.out.println();
for (String str:set
) {
System.out.print(str+" ");
}
System.out.println();
//map比较特殊
Iterator<Map.Entry<String,String>> entries = map.entrySet().iterator();
while (entries.hasNext()){
Map.Entry<String,String >entry = entries.next();
String key = entry.getKey();
String value = entry.getValue();
System.out.println(key+":"+value);
}
}
}
方式二:注解方式
1.去掉bean.xml
- 删除bean.xml文件,删除ApplicationContext这两行代码
- IUserClientServiceImpl加注解 @Service; IUserClientDaoImpl 加注解 Repository
2.@Component
@Component 相当于配置一个bean标签,出现的位置:类
属性值value,用于指定bean的id,如果不写该参数则它的默认值是当前类的短命首字母改小写。
衍生的三个注解(作用和component一模一样)
- Controller:用于表现层注解
- Service:用于业务层注解
- Repository:用于持久层注解 (Dao)
所以,把第一点中写的DaoImpl中的component替换为Repository,把ServiceImpl中的component换为Service
3. @Autowired
自动按照类型注入,不关心bean的id。
**注意:**一定不能出现二义性。也就是说如果有两个(如下图),则不能被识别。
整体代码
- 目录结构
- dao层 IUserClientDao.java
public interface IUserClientDao {
//保存客户信息
void saveCustom();
}
- IUserClientDaoImpl
import com.peach.dao.IUserClientDao;
import org.springframework.stereotype.Repository;
@Repository("userClientDao")
public class IUserClientDaoImpl implements IUserClientDao {
@Override
public void saveCustom() {
System.out.println("调用持久层");
}
}
- service层 IUserClientService.java
public interface IUserClientService {
//保存客户信息
void saveCustom();
}
- IUserClientServiceImpl.java
@Service("userClientService")
public class IUserClientServiceImpl implements IUserClientService {
/**
* 这个是通过构造器注入的
* */
@Autowired
@Qualifier("userClientDao")
// @Resource(name = "userClientDao")
private IUserClientDao userClientDao;
@Value("peach")
private String name;
@Override
public void saveCustom() {
System.out.println(name);
System.out.println("业务层调用持久层");
userClientDao.saveCustom();
}
}