Spring
一、spring
1.1、优点
spring是一个开源的免费的框架(rongq)
spring是一个轻量级的、非入侵式的框架
控制反转(IOC),面向切面编程(AOP)
支持事务的处理,对框架整合的支持
1.2、spring组成及扩展
二、IOC本质推导
使用maven新建一个项目
添加一个UerDao接口
public interface UserDao {
void getUser();
}
添加一个UserDao实现类
public class UserDaoImpl implements UserDao{
@Override
public void getUser() {
System.out.println("获取用户数据");
}
}
新建一个UserService接口
public interface UserService {
void getUser();
}
添加一个UserService实现类
import com.heng.dao.UserDao;
import com.heng.dao.UserDaoImpl;
//实现UserService接口
public class UserServiceImpl implements UserService {
private UserDao userdao = new UserDaoImpl();
@Override
public void getUser() {
//调用dao层方法
userdao.getUser();
}
}
添加测试类,模拟controller
import com.heng.dao.UserDao;
import com.heng.dao.UserDaoImpl;
//实现UserService接口
public class UserServiceImpl implements UserService {
private UserDao userdao = new UserDaoImpl();
@Override
public void getUser() {
//调用dao层方法
userdao.getUser();
}
}
紧接着我们要去使用MySql的话 , 我们就需要去UserService实现类里面修改对应的实现 :
package com.heng.dao;
public class UserDaoMySqlIpml implements UserDao {
@Override
public void getUser() {
System.out.println("获取MySql用户数据");
}
}
这时又要在测试类写一个测试
private UserDao userDao = new UserDaoMySqlIpml(); // 修改实例对象
@Override
public void getUser() {
userDao.getUser(); // 调用Dao层方法
}
}
如果这样的需求很多,这时候这种设计就会耦合很高,不适合快速开发
方法改进
UserService的实现类不是直接去New一个新的实例,而是留出set接口,让调用者决定选择哪个具体的Dao实现,当然这其中有多态的思想在里面:
public class UserServiceImpl implements UserService {
private UserDao userDao;
// 利用set方法实现
public void setUserDao(UserDao userDao) {
this.userDao = userDao;
}
@Override
public void getUser() {
userDao.getUser();
}
}
接着测试类
public class MyTest {
public static void main(String[] args) {
UserService service = new UserServiceImpl();
((UserServiceImpl) service).setUserDao(new UserDaoMySqlIpml());
service.getUser();
}
// print "获取MySql用户数据"
}
虽然只是一个简单的例子,但其中包含的设计思想确实比较高级的:
- 以前所有东西都是由程序去进行控制创建
- 而现在使用了set注入,主动权交给了调用者
- 程序不用去管怎么创建,而是专注于业务逻辑的实现,耦合性大大降低 . 这也就是IOC的原型 。
IOC本质
**
控制反转(IOC)是一种设计思想,依赖注入(DI)是实现IOC的一种方式。在没有IOC的程序中,我们使用面向对象编程,对象的创建和对象之间的依赖完全硬编码在程序中,对象的创建由程序自己控制,控制反转后对象的创建转移给第三方,也就是“获得依赖对象的方式反转了”。
依赖注入
IOC的另外的名字叫做依赖注入(Dependency Injection),所谓的依赖注入,就是由IOC容器在运行期间,动态地将某种依赖关系注入到对象之中。所以,依赖注入(DI)和控制反转(IOC)是从不同的角度的描述的同一件事情,就是指通过引入IOC容器,利用依赖关系注入的方式,实现对象之间的解耦
三、springhello
1、新建一个maven包,添加UserDao类
package com.heng.dao;
public class UserDao {
private String string;
public UserDao() {
}
public String getString() {
return string;
}
public void setString(String string) {
this.string = string;
}
@Override
public String toString() {
return "UserDao{" +
"string='" + string + '\'' +
'}';
}
}
2、在resource下新建一个beans.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">
<!-- 使用spring创建对象-->
<!--
类型 变量名 = new 类型()
UerDao hello = new UserDap();
id就是hello 然后class就是全路径下的包
name就是实例化后的变量
value就是把spring赋给string这个变量
-->
<bean id="hello" class="com.heng.dao.UserDao">
<property name="string" value="spring"/>
</bean>
</beans>
3、新建测试类
import com.heng.dao.UserDao;
import org.springframework.context.ApplicationContext;
import org.springframework.context.support.ClassPathXmlApplicationContext;
public class MyTest {
public static void main(String[] args) {
//写死的这一行
ApplicationContext Context = new ClassPathXmlApplicationContext("beans.xml");
//将id传入
UserDao hello = (UserDao) Context.getBean("hello");
System.out.println(hello.toString());
}
}
4、?思考:
在上面的bean.xml里面,是没有实例化对象的,
那么是谁创建了对象了?
是spring
那对象的属性是怎么设置的?
对象的属性是由spring容器设置的
这个过程就叫控制反转:
控制:谁来和控制对象的创建,传统应用程序的对象是由程序本身控制创建的,例如Hello hello = new Hello();使用spring后,对象是由spring创建的。
反转:程序本身不创建对象,而变成被动的接收对象。
依赖注入:就是利用set方法来进行注入的
IOC是一种编程思想,由主动的编程变成被动的接受。