该模块涉及Spring中的set注入,IOC原型,实现控制反转,希望大家能够认真的理解!
1、编写Dao接口
public interface UserDao {
//定义接口方法,获取用户数据
void getUser();
}
2、编写接口实现类继承Dao接口
public class UserDaoImpl implements UserDao{
@Override
public void getUser() {
System.out.println("获取用户数据!");
}
}
3、编写service接口
public interface UserService {
void getUser();
}
4、编写service实现类
public class UserServiceImpl implements UserService{
//想要实现业务层调用Dao层,先在业务层创建Dao层对象(组合的理念)
private UserDao userDao = new UserDaoImpl();
@Override
public void getUser() {
userDao.getUser();
}
}
5、测试
public class MyTest {
public static void main(String[] args) {
//创建业务层对象
UserServiceImpl service = new UserServiceImpl();
//调用业务层方法
service.getUser();
}
}
7、新需求,如果我们想要在Dao层多加一个需求,需要怎么实现调用呢?
新需求:
public class UserDaoMysqlImpl implements UserDao{
@Override
public void getUser() {
System.out.println("通过Mysql方法,获取用户数据!");
}
}
8、在service实现类中创建UserDaoMysqlImpl对象
public class UserServiceImpl implements UserService{
//想要实现业务层调用Dao层,先在业务层创建Dao层对象(组合的理念)
private UserDao userDao = new UserDaoMysqlImpl();
@Override
public void getUser() {
userDao.getUser();
}
}
9、测试
public class MyTest {
public static void main(String[] args) {
//创建业务层对象
UserServiceImpl service = new UserServiceImpl();
//调用业务层方法
service.getUser();
}
}
10、执行结果
我们不难发现,service实现类中要重新创建DaoImpl对象,新需求的出现会改变原来代码的功能,耦合性极高!假设我们这样的需求成千上万,这种方式根本就无法实现,每次变动都需要改动大量的代码,牵一发而动全身!!!
1、新需求中会有多个Dao的实现类
2、在service的实现类中使用set注入
public class UserServiceImpl implements UserService {
//想要实现业务层调用Dao层,先在业务层创建Dao层对象(组合的理念)
//这里直接创建接口的对象,便于调用接口实现类的方法(多态)
private UserDao userDao;
/* set注入:运用多态的理念,当有多个Dao实现类的时候,我们在Servlet中创建UserServiceImpl对象,
直接调用这个setUserDao,动态传入需要用到的实现类对象
就可以实现动态调用不同的Dao实现类*/
public void setUserDao(UserDao userDao) {
this.userDao = userDao;
}
@Override
public void getUser() {
userDao.getUser();
}
}
3、测试中如果我们想要调用其他的Dao实现类方法,可以这样调用
public class MyTest {
public static void main(String[] args) {
//创建业务层对象
UserServiceImpl service = new UserServiceImpl();
//调用set方法,将需要用到的实现类传进去,就可以实现不改动代态调用码,动
service.setUserDao(new UserDaoOracleImpl());
//调用业务层方法
service.getUser();
}
}
4、执行结果
总结二者的区别:
之前,在service实现类中,程序都是主动创建对象,控制权在程序员手上!
而现在我们使用了set注入,程序不在具有主动性,而是被动的接收对象!
仔细思考一下,之前所有的东西都是由程序进行控制创建,而现在是由我们自行控制创建对象,把主动权交给了调用者,程序不用再去管怎么创建,怎么实现,而是更多的关注业务的实现,它只负责提供一个set接口,这样耦合性大大的被降低了,这也就是我们的IOC原型理念!
1、配置Beans.xml文件(详情见代码中的注释)
2、测试
public class MyTest {
public static void main(String[] args) {
//获取Spring容器
ApplicationContext context = new ClassPathXmlApplicationContext("beans.xml");
//容器获取到,需要哪个对象直接通过getBean获取即可
UserServiceImpl serviceImpl = (UserServiceImpl) context.getBean("serviceImpl");
//我们在配置文件中已经给serviceImpl的userdao属性注入了mysqlImpl对象,这里直接调用getUser方法即可
serviceImpl.getUser();
}
}
3、控制台打印结果
可见,通过由Spring容器统一对对象进行创建、管理和装配,使得调用者不需要去代码中修改,只在配置文件中按照需求修改即可,而我们的程序只需要被动的接收我们配置好的对象就可以,简单方便!!!!!!
带你使用IOC容器编写第一个HelloSpring代码!
一、创建实体类
public class Hello {
private String str;
public String getStr() {
return str;
}
public void setStr(String str) {
this.str = str;
}
@Override
public String toString() {
return "Hello{" +
"str='" + str + '\'' +
'}';
}
}
二、去Bean.xml文件配置实体类
三、测试
public class MyTest {
public static void main(String[] args) {
/*获取Application的上下文对象!!!
*
* */
ClassPathXmlApplicationContext context = new ClassPathXmlApplicationContext("beans.xml");
/*获取对象的方法
* 由于我们已经将这个实体类在Bean.xml文件中配置,所以不需要再new对象
* 直接通过Application的上下文对象调用getBean方法就能获得实体类对象
* 里面传的参数是Bean.xml配置文件中实体类的id*/
Hello hello = (Hello) context.getBean("hello");
//测试调用实体类中的方法
System.out.println(hello.toString());
}
}
四、控制台结果
结合我们第一个HelloSpring程序,这个过程就叫做控制反转
控制:谁来控制对象的创建,传统应用程序的对象是由程序本身控制创建的,使用Spring后,对象是由Spring来创建的
反转:程序本身不创建对象,而变成了被动的接收对象
public class MyTest {
public static void main(String[] args) {
/*获取Application的上下文对象!!!
*也就是获取Spring容器
* */
ApplicationContext context = new ClassPathXmlApplicationContext("beans.xml");
/*获取对象的方法
* 由于我们已经将这个实体类在Bean.xml文件中配置,所以不需要再new对象
* 直接通过Application的上下文对象调用getBean方法就能获得实体类对象
* 里面传的参数是Bean.xml配置文件中实体类的id*/
Hello hello = (Hello) context.getBean("hello");
//测试调用实体类中的方法
System.out.println(hello.toString());
}
}
依赖注入:就是利用set方法进行注入
只有实体类中写了set方法,我们才能在Bean,xml配置文件中对实体类的属性进行修改
测试:
1、将实体类中的set方法删掉
2、bean.xml中的属性名爆红,意味着无法进行相关的操作
IOC是一种编程思想,由主动的编程变成被动的接收,由对象由Spring来创建、管理和装配!!!!!!
一、IOC默认使用实体类的无参构造进行对象的创建
1、定义一个实体类
2、在bean.xml配置文件配置实体类
4、控制台结果
二、如何用有参构造进行创建对象呢?
准备工作:
先在实体类中增加一个带参构造(声明了带参构造那么默认的无参构造就消失了),并且定义一个方法
1、通过实体类的属性下标index进行创建和赋值
按照属性的顺序从0开始,进行赋值
2、通过属性的类型进行赋值(有局限性,如果我的实体类中有多个相同类型的属性,那么就无法识别了)
3、可以直接通过参数名对属性进行赋值
控制台打印结果:
总结:在配置文件加载的时候,容器中管理的对象就已经被初始化了!!!
至此,你对IOC的概念、他究竟如何实现控制反转以及实现的方法已经掌握,后续会持续更新关于Spring的技术讲解,敬请期待!