Spring的核心是控制反转(IoC)和面向切面(AOP)
方便解耦,简化开发 (高内聚低耦合)
• Spring就是一个大工厂(容器),可以将所有对象创建和依赖关系维护,交给Spring管理
• spring工厂是用于生成bean
AOP编程的支持
• Spring提供面向切面编程,可以方便的实现对程序进行权限拦截、运行监控等功能
声明式事务的支持
方便程序的测试
• Spring对Junit4支持,可以通过注解方便的测试Spring程序
方便集成各种优秀框架
• Spring不排斥各种优秀的开源框架,其内部提供了对各种优秀框架(如:Struts、Hibernate、MyBatis、Quartz等)的直接支持
降低JavaEE API的使用难度
• Spring 对JavaEE开发中非常难用的一些API(JDBC、JavaMail、远程调用等),都提供了封装,使这些API应用难度大大降低
1.IOC控制反转
将我们创建对象的控制权反转交给spring去创建
- 之前创建对象是这么写的
UserService userService = new UserServiceImpl();
userService.addUser();
- 现在都由spring来创建,后面开发也都通过扫描配置文件里注入的bean,对象直接从spring容器获取不需要自己创建
在xml里配置bean
<bean id="userServiceId" class="com.itheima.a_ioc.UserServiceImpl"></bean>
1 获得容器
String xmlPath = "com/itheima/a_ioc/beans.xml";
ApplicationContext applicationContext = new ClassPathXmlApplicationContext(xmlPath);
2获得内容 -- 不需要自己new,都是从spring容器通过id获得
UserService userService = (UserService) applicationContext.getBean("userServiceId");
userService.addUser();
2.DI依赖注入
service里是这么写的,通过setBookDao方法进行注入bookDao
private BookDao bookDao;
public void setBookDao(BookDao bookDao) {
this.bookDao = bookDao;
}
@Override
public void addBook(){
this.bookDao.save();
}
上面可以像下面这样用spring配置文件实现,使用<property> 用于进行属性注入
<!-- 创建service -->
<bean id="bookServiceId" class="com.itheima.b_di.BookServiceImpl" >
<property name="bookDao" ref="bookDaoId"></property>
</bean>
<!-- 创建dao实例 -->
<bean id="bookDaoId" class="com.itheima.b_di.BookDaoImpl"></bean>
3.核心Api
BeanFactory :这是一个工厂,用于生成任意bean,采取延迟加载,第一次getBean时才会初始化Bean,懒加载
ApplicationContext:是BeanFactory的子接口,功能更强大。(国际化处理、事件传递、Bean自动装配、各种不同应用层的Context实现)。当配置文件被加载,就进行对象实例化,饿汉式,直接会实例bean
ClassPathXmlApplicationContext 用于加载classpath(类路径、src)下的xml
加载xml运行时位置 --> /WEB-INF/classes/...xml
FileSystemXmlApplicationContext 用于加载指定盘符下的xml
加载xml运行时位置 --> /WEB-INF/...xml
通过java web ServletContext.getRealPath() 获得具体盘符
4.装配bean
- 默认构造
<bean id="" class=""> - 静态工厂
常用与spring整合其他框架(工具)
静态工厂:用于生成实例对象,所有的方法必须是static
<bean id="" class="工厂全限定类名" factory-method="静态方法">
例如:bean.xml配置文件
<bean id="userServiceId" class="com.itheima.c_inject.b_static_factory.MyBeanFactory" factory-method="createService"></bean>
public class MyBeanFactory {
/**
* 创建实例
* @return
*/
public UserService createService(){
return new UserServiceImpl();
}
}
String xmlPath = "com/itheima/c_inject/b_static_factory/beans.xml";
ApplicationContext applicationContext = new ClassPathXmlApplicationContext(xmlPath);
UserService userService = applicationContext.getBean("userServiceId" ,UserService.class);
userService.addUser();
通过userServiceId获得factory并调用createService方法
- 实例工厂
必须先有工厂实例对象,通过实例对象创建对象。提供所有的方法都是“非静态”的。
5.作用域

singleton 单例,默认值。
prototype 多例,每执行一次getBean将获得一个实例。例如:struts整合spring,配置action多例。
6.生命周期
- 初始化和销毁
<bean id="" class="" init-method="初始化方法名称" destroy-method="销毁的方法名称">
目标类
public class UserServiceImpl implements UserService {
@Override
public void addUser() {
System.out.println("e_lifecycle add user");
}
public void myInit(){
System.out.println("初始化");
}
public void myDestroy(){
System.out.println("销毁");
}
}
spring配置
<!--
init-method 用于配置初始化方法,准备数据等
destroy-method 用于配置销毁方法,清理资源等
-->
<bean id="userServiceId" class="com.itheima.e_lifecycle.UserServiceImpl"
init-method="myInit" destroy-method="myDestroy" ></bean>
<!-- 将后处理的实现类注册给spring -->
<bean class="com.itheima.e_lifecycle.MyBeanPostProcessor"></bean>
测试
@Test
public void demo02() throws Exception{
//spring 工厂
String xmlPath = "com/itheima/e_lifecycle/beans.xml";
ClassPathXmlApplicationContext applicationContext = new ClassPathXmlApplicationContext(xmlPath);
UserService userService = (UserService) applicationContext.getBean("userServiceId");
userService.addUser();
//要求:1.容器必须close,销毁方法执行; 2.必须是单例的
//applicationContext.getClass().getMethod("close").invoke(applicationContext);
// * 此方法接口中没有定义,实现类提供
applicationContext.close();
}
BeanPostProcessor 后处理Bean
spring 提供一种机制,只要实现此接口BeanPostProcessor,并将实现类提供给spring容器,spring容器将自动执行,在初始化方法前执行before(),在初始化方法后执行after() 。 配置<bean class="">
spring提供工厂勾子,用于修改实例对象,可以生成代理对象,是AOP底层。
public class MyBeanPostProcessor implements BeanPostProcessor {
@Override
public Object postProcessBeforeInitialization(Object bean, String beanName) throws BeansException {
System.out.println("前方法 : " + beanName);
return bean;
}
@Override
public Object postProcessAfterInitialization(final Object bean, String beanName) throws BeansException {
System.out.println("后方法 : " + beanName);
// bean 目标对象
// 生成 jdk 代理
return Proxy.newProxyInstance(
MyBeanPostProcessor.class.getClassLoader(),
bean.getClass().getInterfaces(),
new InvocationHandler(){
@Override
public Object invoke(Object proxy, Method method, Object[] args) throws Throwable {
System.out.println("------开启事务");
//执行目标方法
Object obj = method.invoke(bean, args);
System.out.println("------提交事务");
return obj;
}});
}
}
将后处理的实现类注册给spring
<bean class="com.itheima.e_lifecycle.MyBeanPostProcessor"></bean>
问题1:后处理bean作用某一个目标类,还是所有目标类?
所有
问题2:如何只作用一个?
通过“参数2”beanName进行控制
Bean的生命周期,生命周期详情
- instantiate bean对象实例化
- populate properties 封装属性
- 如果Bean实现BeanNameAware 执行 setBeanName
- 如果Bean实现BeanFactoryAware 或者 ApplicationContextAware 设置工厂 setBeanFactory 或者上下文对象 setApplicationContext
- 如果存在类实现 BeanPostProcessor(后处理Bean) ,执行postProcessBeforeInitialization
- 如果Bean实现InitializingBean 执行 afterPropertiesSet
- 调用<bean init-method="init"> 指定初始化方法 init
- 如果存在类实现 BeanPostProcessor(处理Bean) ,执行postProcessAfterInitialization
- 执行业务处理
- 如果Bean实现 DisposableBean 执行 destroy
- 调用<bean destroy-method="customerDestroy"> 指定销毁方法 customerDestroy
网友评论