1.spring的核心俩大类 IOC 和AOP(任何一个spring的项目离不开ioc)
要了解Ioc入手点:
1. 概念:
控制反转(Inversion of Control)------>它是一种设计思想。
2. 目的:
降低程序之间的耦合度。(而不是消除)
剖析概念:控制的是什么?反转的又是什么呢。
我们举个例子:以往:我们一个类(Student)中需要调用另一个类(Couse)中的(study)方法。
1
> . 在Student类中 ,实例化一个couse对象再调用study方法
> public class Student{
> Couse cs=new Couse();
> cs.study();
> }
这样对Student类来说是:我需要couse类中的方法,我就自己创建它。这就是(主动控制)。
这样的弊端: 就是student类和couse类之间的耦合度太高。为了降低耦合程度,我们引入了反转控制的概念,即spring的IOC
IOC:将自主创建对象的权利,交给spring来管理。以后我们需要什么样的对象,我们自己不创建,而是像spring容器要。这样就把我们主动控制对象,以及对象的生命周期,反转给了spring,交由它来负责。这就是控制反转,也叫反转控制。
那么概念搞清楚后,我们就要了解spring是如何替我们管理bean对象的呢?
首先了解spring创建bean对象的三种方式:
-
第一种创建bean的方式
使用默认构造函数创建,配以id和class属性之后,没有别的标签,就是默认构造函数创建此时如果类中没有默认构造函数,对象无法被创建。
<bean id="UserDao" class="com.zrj.dao.impl.UserDaoImpl"></bean>
-
第二种创建bean的方式
使用普通工厂类中的方法创建对象
<bean id="factoryMy" class="com.zrj.factory.factoryMy"></bean>
<bean id="UserService" factory-bean="factoryMy" factory-method="getUserServiceImpl"></bean>
-
第三种创建bean的方式
使用普通工厂类中的静态方法创建对象
<bean id="staticfactoryMy" class="com.zrj.factory.StaticfactoryMy" factory-method="getUserServiceImpl"></bean>
再来了解bean的作用范围
默认是单例的(对象只会被创建一次)
bean中有个属性:
scope
作用:指定bean的作用范围
取值:singleton 单例(默认值)
prototype 多例
request 作用于web应用的请求范围
session 作用于web应用的会话范围
global-session 作用于集群环境的会话范围(全局会话),当不是集群环境,它就是session
接下来再了解bean的生命周期:(这里分单例跟多例的情况)
单例的bean
顾名思义就是:
出生:容器被初始化时对象被创建
活着:容器在对象在
死亡:容器销毁对象消亡
总结:生命周期跟容器相同
多例的bean
出生:当我们什么时候用,spring再为我们创建
活着:对象只要在使用过程中,就一直活在
死亡:当对象长时间不用时,或者没有其他对象对他的引用时,java的垃圾 回收机制会帮我们回收处理。
那么spring创建bean的过程就是依赖注入的过程:
注入的3种方式:
构造器注入
bean 标签内部使用一个标签 constroctor-argsetter注入
bean 标签内部使用一个标签 property接口的注入
至此IOC的体现已经结束,我们怎么去获取容器中的bean对象呢?
1.首先我们需要获得容器
这里用一个接口叫 ApplicationContext。它下面有3个常用的实现类。
- ClassPathXmlApplicationContext
注意:它可以加载类路径下的配置文件(xxx.xml),要求配置文件必须在类路径下。不在的,创建不了.
ApplicationContext ac = new ClassPathXmlApplicationContext("xxx.xml");
- FileSystemXmlApplicationContext
它可以加载磁盘任意路径下的配置文件(必须有访问权限)
ApplicationContext ac = new FileSystemXmlApplicationContext("D:\\config\\xxx.xml");
- AnnotationConfigApplicationContext
它是用于读取注解创建容器的
核心容器的俩个接口引发的问题:
- ApplicationContext 单例对象适用 :创建对象采取的策略是:立即加载的方式,即 一读完配置文件就创建文件中配置的对象
- BeanFactory 多例对象适用 :它在构建容器时,采取的策略是:延迟加载(懒加载),什么时候需要这个对象,我再创建。
**
接下来我们说说通过注解的方式来创建对象,并存入spring容器。
前提是需要在xml中配置spring容器要扫描的包
比如配置到com.zrj的包路径下,表示该路径下的所有注解都会被spring容器扫描。
<context:component-scan base-package="com.zrj"></context:component-scan>
- 第一种注解,用来创建bean对象的
@Component 将当前类对象存入spring容器中
下面的这3个注解的作用和Component一模一样,是spring框架为我们提供明确的3层使用的注解,使3层对象跟家清晰
@Controller
@Service
@Repostory
- 第二种用于注入数据的
@Autowired 自动按照类型注入,只要容器中有一个唯一的bean’对象类型,就可以注入成功
@Resource 根据bean的id注入
注意:以上的2个注解只能注入bean类型,不能注入String类型和基本类型,集合类型只能通过xml方式注入
@Value 用于注入基本类型和String类型的数据 ,属性value 用于指定数据的值,也可以使用spring的el表达式指定,${}
上面讲spring中的bean对象的配置都通过注解来实现了,那么能不能去除配置文件呢?
首先需要将扫描的包的配置去除,就可以通过下面这个注解实现
@ComponentScan(basePackages = “com.zrj”)
那么接下来还有一些配置文件中的约束等等信息怎么办呢?
可以通过自定义配置类来完成。
在自定义类上加入@Configuration注解
该类就相当于配置 文件的xml
@Configuration
@ComponentScan(basePackages = "com.zrj")
public class XmlConfig {
// <bean id="IUserService" class="com.zrj.service.impl.UserServiceImpl"></bean>
@Bean 作用:将当前的方法的返回值作为bean对象,存入spring的ioc容器中
public IUserService getUserService(){
return new UserServiceImpl();
}
}
接下来我们需要将该配置类加载进我们的程序中,web应用可以在web.xml中配置。
还有就是我们前面讲到了
AnnotationConfigApplicationContext 他是用来加载注解配置的
AnnotationConfigApplicationContext ac=new AnnotationConfigApplicationContext();
ac.register(configXml.class);
ac.refresh();
然后就可以通过ac对象调用配置类中的bean对象了。
AccountService accountService = ac.getBean("accountService", AccountService.class);