问题1:代码耦合高:
public class EmployeeServiceImpl {
//依赖DAO
private IEmployeeDAO employeeDAO = new EmployeeDAOImpl();
}
问题:若把IEmployeeDAO的实现改成:EmployeeDAOHibernateImpl.
----->解决方案:简单工厂设计模式
----->把创建对象的职责交给工厂来管理.
到底工厂创建哪一个类的对象呢?我们是配置在配置文件中的(properties/xml).
问题2:控制事务的繁琐:
对于事务操作,代码冗余,必须在所有需要控制事务的地方,手动用代码完成几乎完全相同的事务控制逻辑,开发效率低下,并且难以方便的处理事务嵌套需求。
如何降低业务逻辑部分之间耦合度,提高程序的可重用性,同时提高开发的效率!--->AOP
EmployeeService{
public void save(...){
开启事务
dao.save(...);
提交事务
}
public void update(...){
开启事务
dao.update(...);
提交事务
}
}
主要分散在方法前后,在真正的业务操作前后的代码,我们可以使用面向切面编程来解决.
是一种设计思想,好比于MVC。就是将原本在程序中手动创建对象的控制权,交由Spring框架来管理。
正控:若调用者需要使用某个对象,其自身就得负责该对象的创建。
反控:调用者只管负责从Spring容器中获取需要使用的对象,不关心对象的创建过程,也就是把创建对象的控制权反转给了Spring框架。
举例:如果你现在需要打电话,那么你需要创造一个手机,这个就是“正控”;“反控”就是你不必创造手机,你可以找到一个工厂,那里面会有你需要的手机,直接拿来用就好。
从字面上分析:
步骤
1.准备jar包
spring-beans-4.1.2.RELEASE.jar
spring-core-4.1.2.RELEASE.jar
报错再添加:
com.springsource.org.apache.commons.logging-1.1.1.jar
2.开发HelloWorld程序
3.在applicationContext.xml中完成配置
4.启动容器
5.从容器中得到bean
6.调用bean相应的方法
相应代码贴图
## Spring管理bean的原理 ## 什么是BeanFactory: Spring最基本的接口,表示Spring容器——生产bean对象的工厂,负责配置,创建和管理bean。 备注:bean是Spring管理的单位,在Spring中一切都是bean. 深入Spring管理bean的原理。 1、通过Resource对象加载配置文件; 2、解析配置文件,得到指定名称的bean; 3、解析bean元素,id作为bean的名字,class用于反射得到bean的实例
## getBean方法的三种签名 ## 1,按照类型拿bean: world=factory.getBean(HelloWorld.class); 要求在Spring中只配置一个这种类型的实例,否则报错; ---------------------------------------------------------------- 2,按照bean的名字拿bean: world=(HelloWorld)factory.getBean("hello2"); 按照名字拿bean不太安全; ---------------------------------------------------------------- 3,按照名字和类型:(推荐) world=factory.getBean("hello", HelloWorld.class);
在Spring配置中,id和name属性都可以定义bean元素的名称,不同的是:
id属性,遵守XML语法的ID约束(唯一)。必须以字母开始,可以使用字母、数字、连字符、下划线、句话、冒号,不能以“/”开头。
name属性,就可以使用很多特殊字符,比如在Spring和Struts1或Spring MVC的整合中,就得使用name属性来的定义bean的名称。
注意:从Spring3.1开始,id属性不再是ID类型了,而是String类型,也就是说id属性也可以使用“/”开头了,而bean元素的id的唯一性由容器负责检查。(鼓掌)
当然也使用name属性为元素起多个别名,多个别名之间使用逗号或空格隔开,在代码中依然使用BeanFactory对象.getBean(...)方法获取。
或则
Spring中引入其他配置文件:
使用import元素注意:
1、默认情况下,从classpath的根路径寻找。
2、可以使用前缀来定位文件的基础位置:
①:[classpath:]:后面的文件从classpath路径开始找(推荐);[注意classloader的问题。]
②:[file:]:后面的文件使用文件系统的路径开始找;
注意:只有当框架中实现了Resource接口才能够识别上述的前缀标识符。因此只有Spring框架中使用上述前缀。
@Controller
public class SpringtestTest {
// 自动把spring容器中的bean对象设置到这里来
@Autowired
private SomeBeanController bean;
@RequestMapping("/springtest1")
public void springtest1() throws Exception{
bean.sayHello();
}
}
IoC容器:
BeanFactory:是Spring中最底层的接口,只提供了最简单的IoC功能,负责配置,创建和管理bean。
在应用中,一般不使用BeanFactory,而推荐使用ApplicationContext(应用上下文),原因如下。
BeanFactory和ApplicationContext的区别:
1、ApplicationContext继承了BeanFactory,拥有了基本的IoC功能;
2、除此之外,ApplicationContext还提供了以下的功能:
①、支持国际化;
②、支持消息机制;
③、支持统一的资源加载;
④、支持AOP功能;
// 第一种方法:BeanFactory
@RequestMapping("/container1")
public void container1() throws Exception{
Resource res = new ClassPathResource("application.xml");
BeanFactory fac = new XmlBeanFactory(res);
SomeBeanController someBean = fac.getBean("someContainer", SomeBeanController.class);
someBean.sayHello();
}
// 第二种方法:ApplicationContext
@RequestMapping("/container2")
public void container2() throws Exception{
ApplicationContext ctx=new ClassPathXmlApplicationContext("application.xml");
SomeBeanController someBean = ctx.getBean("someContainer", SomeBeanController.class);
someBean.sayHello();
}
// 第三种方法:注入Spring容器
@Autowired
private BeanFactory bean;
private ApplicationContext ctx=new ClassPathXmlApplicationContext("application.xml");
@RequestMapping("/container3")
public void container3() throws Exception{
SomeBeanController someBean1 = bean.getBean("someContainer", SomeBeanController.class);
someBean1.sayHello();
someBean1= ctx.getBean("someContainer", SomeBeanController.class);
someBean1.sayHello();
}
// 第四种方法:注入Spring容器中的bean对象
@Autowired
private SomeBeanController someBean;
@RequestMapping("/container4")
public void container4() throws Exception{
someBean.sayHello();
}
1.ApplicationContext在加载的时候就会创建所有的bean(Web应用建议)
构造函数
----------------------------
Hello,SomeBean!
2.BeanFactory需要等到拿bean的时候才会创建bean (桌面程序)
----------------------------
构造函数
Hello,SomeBean!
控制bean的创建时机/控制是否要延迟加载(了解):
针对于当前xml中所有的bean。
针对于指定的bean:
bean的实例化方式:
①.构造器实例化(无参数构造器),最标准,使用最多。
②.静态工厂方法实例化:解决系统遗留问题
③.实例工厂方法实例化:解决系统遗留问题
④.实现FactoryBean接口实例化:实例工厂变种:集成其他框架使用:LocalSessionFactoryBean
①.构造器实例化(无参数构造器),最标准,使用最多。
bean对象的作用域(bean对象可以存活的时间):
singleton: 单例 ,在Spring IoC容器中仅存在一个Bean实例 (默认的scope)
prototype: 多例 ,每次从容器中调用Bean时,都返回一个新的实例,即每次调用getBean()时 ,相当于执行new XxxBean():不会在容器启动时创建对象
request: 用于web开发,将Bean放入request范围 ,request.setAttribute("xxx") , 在同一个request 获得同一个Bean
session: 用于web开发,将Bean 放入Session范围,在同一个Session 获得同一个Bean
globalSession: 一般用于Porlet应用环境 , 分布式系统存在全局session概念(单点登录),如果不是porlet环境,globalSession 等同于Session
在开发中主要使用 scope="singleton"、 scope="prototype"
对于MVC中的Action使用prototype类型,其他使用singleton
比如DataSource,SessionFactory最终都需要关闭资源:在Bean销毁之前,都要调用close方法.
分析原理:
如果bean的scope="prototype",那么容器只负责创建和初始化,它并不会被spring容器管理。交给用户自己调用.