Spring基础
重要概念:

  1. IOC(Inversion of control):控制反转,控制的是对象的创建,把对象的创建方式进行了反转。
  2. DI(Dependency Injection):依赖注入,即组件之间的依赖关系由容器在运行期决定,由容器动态地将某种依赖关系注入到组件当中,对对象的属性进行注入。
  3. 没有IOC就没有DI。
  4. AOP(Aspect Oriented Programming):面向切面

一.Spring介绍

springmvc工程不重启怎么只刷新jsp_java


类图

注:ClassPathApplicationContext:他只能加载类路径下的配置文件。

FileSystemXmlApplicationContext:它可以加载磁盘任意位置的配置文件。

二.Spring的优点

  1. 方便解耦,简化开发
    Srping是一个大工厂(容器),可以将所有对象的创建和依赖维护关系交给Spring管理。
  2. AOP编程的支持
    Spring提供面向切面编程,可以方便的实现对程序进行权限拦截、运行监控等功能。
  3. 声明式事务的支持
    只需要配置就可以完成对事务的管理,而无须手动编程。
  4. 方便程序的测试
    Spring对Junit4支持,可以通过注解方便的测试Spring程序。
  5. 方便集成各种优秀框架
    Spring不排斥各种优秀的开源框架,其内部提供了对各种优秀框架(如:Struts、Hibernate、MyBatis、Quartz等)的直接支持。
  6. 降低JavaEE API的使用难度
    Spring 对JavaEE开发中非常难用的一些API(JDBC、JavaMail、远程调用等),都提供了封装,使这些API应用难度大大降低。
    (mysql事务,隔离级别,传播行为
    三.Spring入门实例
    1、 创建Java项目。
    2、 导入所需Jar包。

    3.、在项目新建applicationContext.xml配置文件,放在src的lib下面。
    Spring/spring-framework-4.2.4.RELEASE/docs/spring-framework-reference/html/xsd-configuration.html
    applicationContext.xml配置文件注意:
    bean标签中的Id(也可用name,尽量用id,否则在同一个文件中会出错)为操作接口名,class为实际操作类的完整路径名(包名+类名)。



    4、在此处有实例。

springmvc工程不重启怎么只刷新jsp_Spring_02


springmvc工程不重启怎么只刷新jsp_xml_03


5、我自己实现的实例。

springmvc工程不重启怎么只刷新jsp_System_04


注意:此处getBean得到的为Object对象,需要强转为操作接口的对象。ClassPathXmlApplicatipnContext。

6、configurableApplicationContext:让AllicationContext具有刷新(refresh())和关闭(close())功能,是AllicationContext的扩展。

7、使用Spring的IOC进行有参构造方法的对象的实例化

(1)在使用带参数的构造器创建对象时,在中添加且该标签中的name属性必须与对应的实体类中的属性名相同。

springmvc工程不重启怎么只刷新jsp_创建对象_05


(2)引用对象

springmvc工程不重启怎么只刷新jsp_创建对象_06


(3)引用了List集合,name属性要与对象的属性的变量名相同。

springmvc工程不重启怎么只刷新jsp_java_07


四.关于Bean

  1. Bean的生命周期
    (1)Spring对Bean进行实例化
    (2)Spring将值和Bean的引用注入Bean对应的属性中。
    (3)如果Bean实现了BeanNameAware接口,Spring将Bean的ID传递给setBeanName()接口方法。
    (4)如果Bean实现了BeanFactoryAware接口,Spring将调用setBeanFactory()接口方法,将BeanFactory容器实例传入。
    (5)如果Bean实现了ApplicationContextAware接口,Spring将调用setApplicationContext接口方法,将应用上下文的引用传入。
    (6) 如果Bean实现了BeanPostProcessor接口,Spring将调用它们的postProcessBeforeInitialization()接口方法。
    (7) 如果Bean实现了InitializingBean接口,Spring将调用它们的afterPropertiesSet()接口方法。类似地,如果Bean使用init-method声明了初始化方法,该方法也会被调用。
    (8) 如果Bean实现了BeanPostProcessor接口,Spring将调用它们的post-PoressAfterInitialization()方法。
    (9) 此时此刻,Bean已经准备就绪,可以被应用程序使用了,它们将一直驻留在应用上下文中,直到应用上下文被销毁。
    (10) 如果Bean实现了DisposableBean接口,Spring将调用它的destory()接口方法。同样,如果Bean使用destory-method声明了销毁方法,该方法也会被调用。
  2. Bean创建的两种规则以及三种方式以及Bean的作用范围
    (1)Bean创建的两种规则
    所需jar包:

    BeanFactory:提供的是一种延迟加载思想来创建Bean对象,Bean对象什么时候用什么时候创建。代码如下:
@Test
    public void test(){
        ClassPathResource resource = new ClassPathResource("beans.xml");
        BeanFactory factory = new XmlBeanFactory(resource);
        ICustomerService customerService = (ICustomerService) factory.getBean("ICustomerServiceImp");
        customerService.saveCustomer();
    }

执行结果:

springmvc工程不重启怎么只刷新jsp_Spring_08


ApplcationContext:提供的时一种立即加载思想创建Bean对象。只要一解析完配置文件,就立马创建Bean对象。代码如下:

@Test
    public void test(){
         ApplicationContext context = new ClassPathXmlApplicationContext("beans.xml");
         ICustomerService customerService = (ICustomerService) context.getBean("InstanceCustomerService");
		 customerService.saveCustomer();
    }

执行结果:

springmvc工程不重启怎么只刷新jsp_Spring_09


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">
    <!--使用无参构造创建对象-->
    <bean id="ICustomerServiceImp" class="com.renjing.service.imp.ICustomerServiceImp">
    </bean>
</beans>

ICustomerServiceImp类如下:

//客户的业务层实现类
public class ICustomerServiceImp implements ICustomerService {

    public ICustomerServiceImp() {
        System.out.println("bean对象被创建了");
    }

    @Override
    public void saveCustomer() {
        System.out.println("业务层调用持久层");
    }
}

(2)Bean的三种创建方式
① 调用默认无参构造函数创建(用的最多)。
默认情况下,如果类中没有默认无参数构造函数,则创建失败,会报异常。
② 调用静态工厂中的方法创建对象。
需要使用Bean标签的factory-method属性,指定静态工厂中创建对象的方法。
代码如下:

<!--使用静态工厂创建对象-->
    <bean id="staticCustomerService" class="com.renjing.factory.StaticFactory" factory-method="getCustomerService"></bean>

③ 使用实例工厂的方法创建。

<!--使用实例工厂创建对象-->
    <bean id="InstanceFactory" class="com.renjing.factory.InstanceFactory"></bean>
    <bean id="InstanceCustomerService" factory-bean="InstanceFactory" class="com.renjing.factory.InstanceFactory" factory-method="getCustomerService"></bean>

(3)Bean的作用范围
① 他是可以通过配置的方式来调整作用范围。
② 配置的属性:Bean标签的Scope属性。
③ 属性的取值:
Singleton:单例的(默认值)。
xml文件中默认为单例:

public static void main(String[] args) {
        ApplicationContext context = new ClassPathXmlApplicationContext("beans.xml");
        ICustomerService customerService = (ICustomerService) context.getBean("ICustomerServiceImp");
        ICustomerService customerService2 = (ICustomerService) context.getBean("ICustomerServiceImp");
        customerService.saveCustomer();
        System.out.println(customerService==customerService2);
    }

执行结果:

springmvc工程不重启怎么只刷新jsp_java_10


Prototype:多例的(当我们让Spring接管struts的action创建时,action必须配置此值)。

将Bean对象中的scope属性设置为“Prototype”后,

<bean id="ICustomerServiceImp" class="com.renjing.service.imp.ICustomerServiceImp" scope="prototype">

执行结果:

springmvc工程不重启怎么只刷新jsp_创建对象_11


Request:作用范围是一次请求和当前请求的转发。

Session:作用范围时一次会话。

Globalsession:作用范围是一次全局会话。

(4)Bean的生命周期

ICustomeRService的实现类ICustomeRServiceImp:

//客户的业务层实现类
public class ICustomerServiceImp implements ICustomerService {

    public ICustomerServiceImp() {
        System.out.println("bean对象被创建了");
    }

    public void init(){
        System.out.println("对象创建");
    }
    public void destory(){
        System.out.println("对象销毁");
    }

    @Override
    public void saveCustomer() {
        System.out.println("业务层调用持久层");
    }
}

xml配置文件:

<!--使用无参构造创建对象,并设置初始化和销毁的方法-->
    <bean id="ICustomerServiceImp" class="com.renjing.service.imp.ICustomerServiceImp" scope="singleton" init-method="init" destroy-method="destory">

mian函数:

public static void main(String[] args) {
		ApplicationContext context = new ClassPathXmlApplicationContext("beans.xml");
        ICustomerService customerService = (ICustomerService) context.getBean("ICustomerServiceImp");
        customerService.saveCustomer();
}

执行结果:

springmvc工程不重启怎么只刷新jsp_java_12


此时,我们只能看到对象的创建,原因在于:线程运行的时候,先将Main函数压栈,等到其他函数弹栈完毕后,Main函数才会弹栈,然后线程上所占用的内存才会被全部释放。还没有调用销毁方法,内存已经全部被释放,故而看不到对象的销毁。

修改代码如下:

public static void main(String[] args) {
        ClassPathXmlApplicationContext context = new ClassPathXmlApplicationContext("beans.xml");
        ICustomerService customerService = (ICustomerService) context.getBean("ICustomerServiceImp");
        customerService.saveCustomer();
        context.close();
    }

执行结果:

springmvc工程不重启怎么只刷新jsp_Spring_13


① 涉及Bean标签的两个属性:

Init-method

Destory-method

② 单例:

出生:容器创建,对象出生。

活着:只要容器在,对象就一直在。

死亡:容器销毁,对象消亡。

③ 多例:

出生:每次使用时,创建对象。

活着:只要对象在使用中,就一直活着。

死亡:当对象长时间不使用,并且也没有别的对象引用时,由java的垃圾回收器回收。