官方文档:https://spring.io/projects/spring-framework#overview
官方下载地址:https://repo.spring.io/ui/native/release/org/springframework/spring/
优点
- Spring是一个开源的免费的框架(容器)!
- Spring是一个轻量级的、非入侵式的框架!
- 控制反转(IOC)、面向切面编程(AOP)!
- 支持事务的处理、对框架整合的支持!
总结一句话:Spring就是一个轻量级的 控制反转 和 面向切面编程 的框架
IoC(Inversion of Control),是一种设计思想,**DI(依赖注入)**是实现IoC得一种方法。
IOC理论推导
一般业务流程:
1.UserDAO层
2.UserDAOImpl实现层
3.UserService接口
4.UserImpl实现类
实例:
1、
public interface UserDao {
void getUser();
}
2、
public class UserDaoImpl implements UserDao{
@Override
public void getUser() {
System.out.println("实现sql");
}
}
3、
public interface UserService {
void getUser();
}
4、
private UserDao userDao = new UserDaoImpl();
private UserDao userDao =new UserDaoMysqlImpl();
@Override
public void getUser() {
userDao.getUser();
}
5:测试、
public class MyTest {
public static void main(String[] args) {
UserService userService = new UserServiceImpl();
userService.getUser();
}
}
在之前的业务中用户的需求可能会影响原来的代码,我们需要根据用户的需求修改原来的代码,比如在dao层中增加多个实现类
2+、
public class UserDaoMysqlImpl implements UserDao{
@Override
public void getUser() {
System.out.println("实现Mysql");
}
}
public class UserDaoOracleImpl implements UserDao{
@Override
public void getUser() {
System.out.println("实现Oracle");
}
}
则UserServiceImpl也需要每次跟着修改
private UserDao userDao = new UserDaoImpl();
private UserDao userDao = new UserDaoMysqlImpl();
@Override
public void getUser() {
userDao.getUser();
}
每次增加都会需要不断修改
修改的成本代价十分昂贵!
我们使用一个Set接口实现,已经发生了革命性的变化!
在UserServiceImpl实现类中利用Set进行动态实现值得注入
public class UserServiceImpl implements UserService {
/*
* 修改之前,测试每次都需要更改 实现类
*
* */
// private UserDao userDao = new UserDaoImpl();
// private UserDao userDao = new UserDaoMysqlImpl();
// @Override
// public void getUser() {
// userDao.getUser();
// }
/*
* 修改之后,利用set进行动态实现值的注入
*
* */
private UserDao userDaoAfter;
public void setUserDaoAfter(UserDao userDaoAfter) {
this.userDaoAfter = userDaoAfter;
}
public void getUser() {
userDaoAfter.getUser();
}
}
实现类
public class MyTest {
public static void main(String[] args) {
// UserService userService = new UserServiceImpl();
// userService.getUser();
UserService userService = new UserServiceImpl();
((UserServiceImpl) userService).setUserDaoAfter(new UserDaoMysqlImpl());
userService.getUser();
}
}
之前,程序式主动创建对象!控制权在程序员手上!
使用set注入后,主动权放在了程序身上,而是变成了被动得接收对象
这种思想,从本质上解决了问题,程序员不用再去管理对象得创建,可以更加专注在业务得实现,系统降低了耦合性。这是IOC得原型!
使用配置文件
<?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
https://www.springframework.org/schema/beans/spring-beans.xsd">
<!-- 使用spring来创建对象,在spring这些都称为Bean
类型 变量名 = new 类型;
bean = 对象 new Hello();
id = 变量名
class = new 的对象
property = 相当于给对象中的属性设置一个值
-->
<bean id="hello" class="helloSpring.pojo.Hello">
<property name="hello" value="Spring"/>
</bean>
<bean id="sqlImpl" class="oneIOC.dao.UserDaoImpl"/>
<bean id="mysqlImpl" class="oneIOC.dao.UserDaoMysqlImpl"/>
<bean id="userServiceImpl" class="oneIOC.service.UserServiceImpl">
<!--ref :引用Spring容器中创建好的对象-->
<property name="userDaoAfter" ref="mysqlImpl"/>
</bean>
</beans>
测试:
public class MyTest {
public static void main(String[] args) {
//获取ApplicationContext;
ClassPathXmlApplicationContext context = new ClassPathXmlApplicationContext("beans.xml");
//容器在手,天下我有,用什么就直接get什么
UserServiceImpl userServiceImpl = (UserServiceImpl)context.getBean("userServiceImpl");
userServiceImpl.getUser();
}
}
IoC创建对象的方式
@Data
@AllArgsConstructor
public class User {
private String name;
public void show(){
System.out.println("name"+name);
}
}
1.使用无参构造创建对象,默认!
2.假设我们要使用有参构造创建对象。
1.下标赋值
<!--下标赋值-->
<bean id="user" class="oneIOC.pojo.User">
<constructor-arg index="0" value="jack"/>
</bean>
2.通过类型创建,不建议使用
<!--类型赋值 不建议使用-->
<bean id="user" class="oneIOC.pojo.User">
<constructor-arg type="java.lang.String" value="jack"/>
</bean>
3.直接通过参数名
<!--直接通过参数名-->
<bean id="user" class="oneIOC.pojo.User">
<constructor-arg name="name" value="jack"/>
</bean>
总结:在配置文件加载的时候,容器中管理的对象就已经初始化了!
<!--起的别名 -->
<alias name="user" alias="erwe"/>
<!--id是bean的唯一标识符,也就是相当于我们学的对象名
class: bean 对象对应的全限定名: 包名 + 类型
name:也是别名,而且name 可以同时取多个别名-->
name="user2 u2,u3;u4
import
一般用于团队开发,它可以将多个配置文件,导入合并为一个,加入不同类需要不同的bean文件。此时可以使用
<import resource="beans.xml"/>
<import resource="beans2.xml"/>
DI依赖注入
构造器注入
Set方式注入【重点】
- 依赖注入:Set注入
- 依赖:bean对象的创建依赖于容器!
- 注入:bean对象中的所有属性,由容器来注入!
【环境搭载】
1.复杂类型
@Data
public class Address {
private String address;
}
2.真实对象
@Data
public class Student {
private String name;
private Address address;
private String[]books;
private List<String> hobbies;
private Map<String,String> card;
private Set<String> games;
private String wife;
private Properties info;
}
3.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
https://www.springframework.org/schema/beans/spring-beans.xsd">
<bean id="address" class="diIoC.pojo.Address"/>
<bean id="student" class="diIoC.pojo.Student">
<!--第一种,普通注入 -->
<property name="name" value="Oh嘻嘻嘻嘻"/>
<!--bean注入,ref-->
<bean id="address" class="diIoC.pojo.Address">
<property name="address" value="东山"/>
</bean>
<!--数组注入 ,ref-->
<property name="books">
<array>
<value>红楼梦</value>
<value>西游记</value>
<value>假面山庄</value>
</array>
</property>
<!--List-->
<property name="hobbies">
<list>
<value>跑步</value>
<value>睡觉</value>
<value>手工</value>
</list>
</property>
<!--Map-->
<property name="card">
<map>
<entry key="身份证" value="11111111111111"/>
<entry key="银行卡" value="9999999999999999"/>
</map>
</property>
<!--Set-->
<property name="games">
<set>
<value>王者荣耀</value>
<value>和平精英</value>
</set>
</property>
<property name="wife">
<null/>
</property>
<property name="info">
<props>
<prop key="学号">2018</prop>
<prop key="性别">女</prop>
</props>
</property>
</bean>
</beans>
4.测试类
public class diIoCTest {
public static void main(String[] args) {
ApplicationContext context = new ClassPathXmlApplicationContext("beandi.xml");
Student student = (Student)context.getBean("student");
System.out.println(student.toString());
}
}
Student(name=Oh嘻嘻嘻嘻,
address=Address(address=东山),
books=[红楼梦, 西游记, 假面山庄],
hobbies=[跑步, 睡觉, 手工],
card={身份证=11111111111111, 银行卡=9999999999999999},
games=[王者荣耀, 和平精英],
wife=null,
info={学号=2018, 性别=女})
P命名 | C命名
不能直接使用需要导入
<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"
xmlns:c="http://www.springframework.org/schema/c"
xsi:schemaLocation="http://www.springframework.org/schema/beans
https://www.springframework.org/schema/beans/spring-beans.xsd">
<!--p命名空间注入,可以直接注入属性的值 property-->
<bean id="user" class="diIoC.pojo.User" p:name="小崽子" p:age="18"/>
<!--c命名空间注入,通过构造器注入,全参构造器 可以-->
<bean id="user1" class="diIoC.pojo.User" c:name="哼哼" p:age="28"/>
</beans>
** 注意:c命名空间注入,必须有全参构造器 **
@Data
@NoArgsConstructor
@AllArgsConstructor
public class User {
private String name;
private int age;
}
bean作用域
1.单例模式(Spring默认机制)
<!--单例模式,Spring默认机制-->
<bean id="user1" class="diIoC.pojo.User" c:name="哼哼" p:age="28" scope="singleton"/>
2.原型模式:每次从容器中get的时候,都会产生一个新的对象!
<!--原型模式-->
<bean id="user1" class="diIoC.pojo.User" scope="prototype"/>
3.其余的request、session、application/这些个只能在web开发中使用到
Bean自动装配
- 自动装配式Spring满足bean依赖的一种方式
- Spring会在上下文中自动寻找,并自动给bean装配属性
- 隐式的自动装配bean【重要】
@Data
@AllArgsConstructor
@NoArgsConstructor
public class People {
private String name;
private Dog dog;
private Cat cat;
}
public class Dog {
public void shout(){
System.out.println("wang~");
}
}
public class Cat {
public void shout(){
System.out.println("miao~");
}
}
<bean id="cat" class="autowireBean.pojo.Cat"/>
<bean id="dog" class="autowireBean.pojo.Dog"/>
<!-- byName 会自动在容器上下文中查找,和自己对象set方法后边的值对应的beanid
byType 会自动在容器上下文中查找,和自己对象属性类型后边的值对应beanid!
-->
<!-- <bean id="people" class="autowireBean.pojo.People" autowire="byName">-->
<bean id="people" class="autowireBean.pojo.People" autowire="byType">
<property name="name" value="我是你的神"/>
</bean>
测试
public class AutoWireTest {
@Test
public void test(){
ClassPathXmlApplicationContext context = new ClassPathXmlApplicationContext("autowireBean.xml");
People people = context.getBean("people",People.class);
people.getCat().shout();
people.getDog().shout();
}
}