[笔记]Spring-Day1 — IOC&DI
学什么
简化开发: Spring框架中提供了两个大的核心技术
IOC
AOP
核心概念
IOC & IOC容器 & Bean
IOC(Inversion of Control)控制反转
不自己new对象,交给容器new -- 解耦
IOC容器负责对象的创建、初始化等一系列工作,其中包含了数据层和业务层的类对象
被创建或被管理的对象在IOC容器中统称为Bean
DI
(Dependency Injection)依赖注入
建立容器中对象与对象之间的绑定关系
service运行需要依赖dao对象
案例
解耦BookDao
pom.xml添加依赖
添加案例中需要的类
添加spring配置文件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" xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans.xsd"> <!--1.导入spring的坐标spring-context--> <!--2.配置bean--> <!--bean标签标示配置bean id属性标示给bean起名字 class属性表示给bean定义类型 注意class不要写成接口类而是实现类,因为bean要找对象 --> <bean id="bookDao" class="com.itheima.dao.impl.BookDaoImpl"/> <bean id="bookService" class="com.itheima.service.impl.BookServiceImpl"/> </beans>
获取IOC容器、从容器中获取对象进行方法调用
```java public class App { public static void main(String[] args) { //获取IOC容器 ApplicationContext ctx = new ClassPathXmlApplicationContext("applicationContext.xml"); //getBean() 方法获取的 Bean 的标识符(id 或 name 属性的值),返回的是一个通用的 Object 类型,我们需要将其转换为 BookService 类型 // BookDao bookDao = (BookDao) ctx.getBean("bookDao"); // bookDao.save(); BookService bookService = (BookService) ctx.getBean("bookService"); bookService.save(); } } ```
运行程序测试
解耦BookService
去除BookServiceImpl中的new,为属性提供setter方法
public class BookServiceImpl implements BookService { //删除业务层中使用new的方式创建的dao对象 private BookDao bookDao; public void save() { System.out.println("book service save ..."); bookDao.save(); //提供对应的set方法 public void setBookDao(BookDao bookDao) { this.bookDao = bookDao; } }
修改配置完成注入
<?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标签标示配置bean id属性标示给bean起名字 class属性表示给bean定义类型--> <bean id="bookDao" class="com.itheima.dao.impl.BookDaoImpl"/> <bean id="bookService" class="com.itheima.service.impl.BookServiceImpl"> <!--配置server与dao的关系--> <!--property标签表示配置当前bean的属性 name属性表示配置哪一个具体的属性/对象名称 ref属性表示参照哪一个bean--> <property name="bookDao" ref="bookDao"/> </bean> </beans>
运行程序
关于bean
bean的基础配置
配置别名 name
name
<!--name:为bean指定别名,别名可以有多个,使用逗号,分号,空格进行分隔-->
<bean id="bookService" name="service service4 bookEbi" class="com.itheima.service.impl.BookServiceImpl">
<property name="bookDao" ref="bookDao"/>
</bean>
配置范围(是否为单例) scode
scode
<!--scope:为bean设置作用范围,可选值为单例singloton,非单例prototype-->
<bean id="bookDao" name="dao" class="com.itheima.dao.impl.BookDaoImpl"/>
</beans>
bean的实例化
构造方法实例化 — 无参构造方法
在BookDaoImpl类中添加一个无参构造函数,并打印一句话,方便观察结果
静态工厂实例化 — 了解即可
实例工厂化 — 额额不太懂
准备一个Dao和DaoImpl类
创建一个工厂类OrderDaoFactory并提供一个普通方法
public class UserDaoFactory {
}
}
创建一个UserDaoFactoryBean的类,实现FactoryBean接口,重写接口的方法
public class UserDaoFactoryBean implements FactoryBean<UserDao> {
//代替原始实例工厂中创建对象的方法
//替代UseDaoFactory的getUserDao方法
public UserDao getObject() throws Exception {
return new UserDaoImpl();
}
//返回所创建类的Class对象
public Class<?> getObjectType() {
return UserDao.class;
}
}
配置文件添加
<bean id="userDao" class="com.itheima.factory.UserDaoFactoryBean"/>
编写AppForInstanceUser运行类,在类中通过工厂获取对象
public class AppForInstanceUser { public static void main(String[] args) { ApplicationContext ctx = new ClassPathXmlApplicationContext("applicationContext.xml"); UserDao userDao = (UserDao) ctx.getBean("userDao"); userDao.save(); } }
bean的生命周期
bean对象从创建到销毁的整体过程
初始化容器
1.创建对象(内存分配)
2.执行构造方法
3.执行属性注入(set操作)
4.执行bean初始化方法
使用bean
执行业务操作
关闭/销毁容器
执行bean销毁方法
代码实现
1.init&destory
//添加两个接口`InitializingBean`, `DisposableBean`并实现接口中的两个方法`afterPropertiesSet`和`destroy` //这样就不用在配置文件里面配置`init-method`和`destroy-method` public class BookServiceImpl implements BookService, InitializingBean, DisposableBean { private BookDao bookDao; public void setBookDao(BookDao bookDao) { this.bookDao = bookDao; } public void save() { System.out.println("book service save ..."); bookDao.save(); } public void destroy() throws Exception { System.out.println("service destroy"); } public void afterPropertiesSet() throws Exception { System.out.println("service init"); } }
2.close —执行destroy方法的内容
//ApplicationContext中没有close方法,需要将ApplicationContext更换成ClassPathXmlApplicationContext ClassPathXmlApplicationContext ctx = new ClassPathXmlApplicationContext("applicationContext.xml"); //运行程序,就能执行destroy方法的内容 ctx.close();
3.注册钩子关闭容器 — 执行destroy方法的内容
ctx.registerShutdownHook();
DI
相关内容
setter注入
简单类型
<bean ...>
<property name="" value=""/>
</bean>
引用类型
<bean ...>
<property name="" ref=""/>
</bean>
构造器注入
简单类型
<bean ...>
<constructor-arg name="" index="" type="" value=""/>
</bean>
引用类型
<bean ...>
<constructor-arg name="" index="" type="" ref=""/>
</bean>
自动配置
不用写配置文件了
类型
按类型(常用)
<bean class="com.itheima.dao.impl.BookDaoImpl"/>
<!--autowire属性:开启自动装配,通常使用按类型装配-->
<bean id="bookService" class="com.itheima.service.impl.BookServiceImpl" autowire="byType"/>
</beans>
按名称 — 有多个相同类型的对象
<bean class="com.itheima.dao.impl.BookDaoImpl"/>
<!--autowire属性:开启自动装配,通常使用按类型装配-->
<bean id="bookService" class="com.itheima.service.impl.BookServiceImpl" autowire="byName"/>
</beans>
按构造方法
集合注入
数组类型数据
<property name="array">
<array>
<value>100</value>
<value>200</value>
<value>300</value>
</array>
</property>
注入List类型数据
<property name="list">
<list>
<value>itcast</value>
<value>itheima</value>
<value>boxuegu</value>
<value>chuanzhihui</value>
</list>
</property>
注入Set类型数据
<property name="set">
<set>
<value>itcast</value>
<value>itheima</value>
<value>boxuegu</value>
<value>boxuegu</value>
</set>
</property>
注入Map类型数据
<property name="map">
<map>
<entry key="country" value="china"/>
<entry key="province" value="henan"/>
<entry key="city" value="kaifeng"/>
</map>
</property>
注入Properties类型数据
<property name="properties">
<props>
<prop key="country">china</prop>
<prop key="province">henan</prop>
<prop key="city">kaifeng</prop>
</props>
</property>
最后更新于