spring(一)

spring

1.什么是spring

Spring是一个开源框架,Spring是于2003 年兴起的一个轻量级的Java 开发框架,由Rod Johnson 在其著作Expert One-On-One J2EE Development and Design中阐述的部分理念和原型衍生而来。它是为了解决企业应用开发的复杂性而创建的。框架的主要优势之一就是其分层架构,分层架构允许使用者选择使用哪一个组件,同时为 J2EE 应用程序开发提供集成的框架。Spring使用基本的JavaBean来完成以前只可能由EJB完成的事情。然而,Spring的用途不仅限于服务器端的开发。从简单性、可测试性和松耦合的角度而言,任何Java应用都可以从Spring中受益。Spring的核心是控制反转(IoC)和面向切面(AOP)。简单来说,Spring是一个分层的JavaSE/EE full-stack(一站式) 轻量级开源框架。 轻量级:与EJB对比,依赖资源少,销毁的资源少。 分层: 一站式,每一个层都提供的解决方案

2.特点

1.方便解耦,简化开发

通过Spring提供的IoC容器,我们可以将对象之间的依赖关系交由Spring进行控制,避免硬编码所造成的过度程序耦合。有了Spring,用户不必再为单实例模式类、属性文件解析等这些很底层的需求编写代码,可以更专注于上层的应用。

2.AOP编程的支持

通过Spring提供的AOP功能,方便进行面向切面的编程,许多不容易用传统OOP实现的功能可以通过AOP轻松应付。

3.声明事物的支持

在Spring中,我们可以从单调烦闷的事务管理代码中解脱出来,通过声明式方式灵活地进行事务的管理,提高开发效率和质量。

4.方便程序的测试

可以用非容器依赖的编程方式进行几乎所有的测试工作,在Spring里,测试不再是昂贵的操作,而是随手可做的事情。例如:Spring对Junit4支持,可以通过注解方便的测试Spring程序。

5.方便集成各种优秀框架

Spring不排斥各种优秀的开源框架,相反,Spring可以降低各种框架的使用难度,Spring提供了对各种优秀框架(如Struts,Hibernate、Hessian、Quartz)等的直接支持。

6.降低Java EE API的使用难度

Spring对很多难用的Java EE API(如JDBC,JavaMail,远程调用等)提供了一个薄薄的封装层,通过Spring的简易封装,这些Java EE API的使用难度大为降低。

7.Java 源码是经典学习范例

3.优点

  • 方便解耦,简化开发 (高内聚低耦合)

    • Spring就是一个大工厂(容器),可以将所有对象创建和依赖关系维护,交给Spring管理

    • spring工厂是用于生成bean

    • 耦合性:也称块间联系。指软件系统结构中各模块间相互联系紧密程度的一种度量。模块之间联系越紧密,其耦合性就越强,模块的独立性则越差。模块间耦合高低取决于模块间接口的复杂性、调用的方式及传递的信息。

  • AOP编程的支持

    • Spring提供面向切面编程,可以方便的实现对程序进行权限拦截、运行监控等功能

  • 声明式事务的支持

    • 只需要通过配置就可以完成对事务的管理,而无需手动编程

  • 方便程序的测试

    • Spring对Junit4支持,可以通过注解方便的测试Spring程序

  • 方便集成各种优秀框架

    • Spring不排斥各种优秀的开源框架,其内部提供了对各种优秀框架(如:Struts、Hibernate、MyBatis、Quartz等)的直接支持

  • 降低JavaEE API的使用难度

    • Spring 对JavaEE开发中非常难用的一些API(JDBC、JavaMail、远程调用等),都提供了封装,使这些API应用难度大大降低

4.spring体系结构

Spring框架是一个分层架构,它包含一系列的功能要素并被分为大约20个模块。这些模块分为Core Container、Data Access/Integration、Web、AOP(Aspect Oriented Programming)、Instrumentation的测试部分,如图所示:

Spring体系结构图

核心容器:beans、core、context、expression

5.spring核心主要两部分:

(1)aop:面向切面编程,扩展功能不修改源代码实现

(2)ioc:控制反转

5.1 ioc 控制反转

Ioc—Inversion of Control,即“控制反转”,不是什么技术,而是一种设计思想。在Java开发中,Ioc意味着将你设计好的对象交给容器控制,而不是传统的在你的对象内部直接控制。

IoC 不是一种技术,只是一种思想,一个重要的面向对象编程的法则,它能指导我们设计出松耦合、更优良的程序。把创建和查找依赖对象的控制权交给了容器,由容器进行注入组合对象,所以对象与对象之间是松散耦合,利于功能复用,更重要的是使得程序的整个体系结构变得非常灵活。

这里的控制指把控制权从应用程序中剥离出来。ioc它可以把创建对象和查找依赖对象的权限交给Ioc容器控制,而不是传统的由这些对象的使用方(消费者)进行创建初始化操作。IoC是一种让服务消费者不直接依赖于服务提供者的组件设计方式,是一种减少类与类之间依赖的设计原则。

为什么Ioc叫控制反转呢,反转了什么呢?传统的程序都是消费者主动创建对象,现在容器帮我们查找及注入依赖对象,而消费者只是被动的接受依赖对象,此为反转。

6.DI是什么?和ioc的区别

6.1DI:依赖注入

指容器复制创建和维护对象之间的依赖关系,而不是通过对象本身复制自己的创建和解决自己的依赖。控制反转是通过依赖注入实现的。

6.2DI和ioc区别与练习

(1)ioc 控制反转

传统资源查找方式:要求组件向容器发起请求,查找资源作为回应,容器适时返回资源。 IOC查找方式:容器主动将资源提供给它所管理的组件,组件只需要选择一个合适的方式来接收资源。 创建对象实例的控制权由代码控制转移到IOC容器控制(new关键字转移到容器),即在XML文件中控制,控制权转移即所 谓的反转,侧重于原理。 (2)DI:依赖注入(Dependecy Injection)

IOC另一种表达方式:组件以一些预先定义好的方式(如setter\getter)接收来自容器的资源注入。 相对于IOC,DI更直接。 创建对象实例时,为这个对象注入属性值和其他对象实例,侧重于实现。

7.属性注入方法

7.1 使用set方法进行注入

Dept.java

package com.syf.bean;
import lombok.AllArgsConstructor;
import lombok.Getter;
import lombok.NoArgsConstructor;
import lombok.Setter;
import java.util.List;
@Getter
@Setter
@NoArgsConstructor
@AllArgsConstructor
public class Dept {
    private Integer id;
    private String deptname;
    private List<Emp> list;
}

Emp.java

package com.syf.bean;
import lombok.AllArgsConstructor;
import lombok.Getter;
import lombok.NoArgsConstructor;
import lombok.Setter;
@Getter
@Setter
@NoArgsConstructor
@AllArgsConstructor
public class Emp {
    private Integer id;
    private String name;
    private int sex;
    private Dept dept;
}

beans2.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" xmlns:p="http://www.springframework.org/schema/p"
       xmlns:util="http://www.springframework.org/schema/util"
​
       xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans.xsd">
<bean id="dept" class="com.syf.bean.Dept" >
    <property name="id" value="001"></property>
    <property name="deptname" value="创业部"></property>
</bean>
    <bean id="emp" class="com.syf.bean.Emp">
        <property name="id" value="1"></property>
        <property name="name">
            <!--属性值包含特殊符号
            1.把<>进行转义
            2.把带特殊符号的内容写到CDATA
        -->
            <value><![CDATA[《张三丰》]]></value>
        </property>
        <property name="sex" value="99"></property>
        <property name="dept">
            <ref bean="dept"></ref>
        </property>
    </bean>
</beans>

测试代码

@Test
    public void test02() {
        //获取配置文件 beans.xml
        ApplicationContext context = new ClassPathXmlApplicationContext("beans2.xml");
        //配置文件的bean  id
        Emp emp=context.getBean("emp",Emp.class);
      System.out.println(emp.getDept().getDeptname()+"\t"+emp.getId()+"\t"+emp.getName()+"\t"+emp.getSex());
​
    }

结果截图:

 

构造方法注入:

Dept.java

package com.syf.bean;
​
import lombok.AllArgsConstructor;
import lombok.Getter;
import lombok.NoArgsConstructor;
import lombok.Setter;
​
import java.util.List;
@Getter
@Setter
@NoArgsConstructor
@AllArgsConstructor
public class Dept {
    private Integer id;
    private String deptname;
    private List<Emp> list;
​
    public Dept(Integer id, String deptname) {
        this.id = id;
        this.deptname = deptname;
    }
}

 

Emp.java

package com.syf.bean;
​
import lombok.AllArgsConstructor;
import lombok.Getter;
import lombok.NoArgsConstructor;
import lombok.Setter;
​
@Getter
@Setter
@NoArgsConstructor
@AllArgsConstructor
public class Emp {
    private Integer id;
    private String name;
    private int sex;
    private Dept dept;
}

beans3.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" xmlns:util="http://www.springframework.org/schema/util"
       xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans.xsd">
<bean id="dept1" class="com.syf.bean.Dept">
    <constructor-arg name="id" value="002"></constructor-arg>
    <constructor-arg name="deptname" value="公益部"></constructor-arg>
</bean>
    <bean id="emp" class="com.syf.bean.Emp">
        <constructor-arg name="id" value="02"></constructor-arg>
        <constructor-arg name="name" value="刘嘉伟"></constructor-arg>
        <constructor-arg name="sex" value="25"></constructor-arg>
        <constructor-arg name="dept">
            <ref bean="dept1"></ref>
        </constructor-arg>
    </bean>
</beans>

测试代码

@Test
    public void test03() {
        //获取配置文件 beans.xml
        ApplicationContext context = new ClassPathXmlApplicationContext("beans3.xml");
        //配置文件的bean  id
        Emp emp=context.getBean("emp",Emp.class);
      System.out.println(emp.getDept().getDeptname()+"\t"+emp.getId()+"\t"+emp.getName()+"\t"+emp.getSex());
    }

结果截图:

 

7.2集合属性的注入

ListTest:

package com.syf.bean;
​
import lombok.AllArgsConstructor;
import lombok.Getter;
import lombok.NoArgsConstructor;
import lombok.Setter;
​
import java.util.Map;
import java.util.Set;
@Getter
@Setter
@NoArgsConstructor
@AllArgsConstructor
public class ListTest {
    private String[] arr;
    private java.util.List<String> list;
    private Map<Integer,String> map;
    private Set set;
}

beans4.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="list" class="com.syf.bean.ListTest" >
    <property name="arr">
        <array>
            <value>I</value>
            <value>Am</value>
            <value>Iron</value>
            <value>Man</value>
        </array>
    </property>
        <property name="list">
            <list>
                <value>I</value>
                <value>Am</value>
                <value>Iron</value>
                <value>Man</value>
            </list>
        </property>
<property name="map">
            <map>
                <entry key="1" value="I"></entry>
                <entry key="2" value="Am"></entry>
                <entry key="3" value="Iron"></entry>
                <entry key="4" value="Man"></entry>
            </map>
        </property>
        <property name="set">
            <set>
                <value>I</value>
                <value>Am</value>
                <value>Iron</value>
                <value>Man</value>
            </set>
        </property>
</bean>
</beans>
        

测试:

@Test
    public void test04() {
        //获取配置文件 beans.xml
        ApplicationContext context = new ClassPathXmlApplicationContext("beans4.xml");
        //配置文件的bean  id
        ListTest list=context.getBean("list", ListTest.class);
        System.out.println(list.getArr());
        System.out.println(list.getList());
        System.out.println(list.getMap());
        System.out.println(list.getSet());

结果截图:

 

8.Spring管理的bean的作用域有

8.1 singleton

在每个Spring IoC容器中,一个bean定义只有一个对象实例。

Car.java

package com.syf.bean;
​
public class Car {
    private String brand;
    private String corp;
    private  double price;
    private int maxpeed;
    public Car(String brand, String corp, double price) {
        this.brand = brand;
        this.corp = corp;
        this.price = price;
    }
    public Car() {
    }
    public String getBrand() {
        return brand;
    }
    public String getCorp() {
        return corp;
    }
    public double getPrice() {
        return price;
    }
    public int getMaxpeed() {
        return maxpeed;
    }
    public void setBrand(String brand) {
        this.brand = brand;
    }
    public void setCorp(String corp) {
        this.corp = corp;
    }
    public void setPrice(double price) {
        this.price = price;
    }
    public void setMaxpeed(int maxpeed) {
        this.maxpeed = maxpeed;
    }
}

Person.java

package com.syf.bean;
​
public class Person {
    private  Car car;
    public Person(Car car) {
        this.car = car;
    }
    public Car getCar() {
        return car;
    }
    public void setCar(Car car) {
        this.car = car;
    }
}
beans.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" xmlns:p="http://www.springframework.org/schema/p"
       xmlns:util="http://www.springframework.org/schema/util"
       xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans.xsd">
<bean id="car" class="com.syf.bean.Car">
    <property name="brand" value="帕萨特"></property>
    <property name="corp" value="大众"></property>
    <property name="price" value="5000"></property>
</bean>
    <bean id="persion" class="com.syf.bean.Person">
        <constructor-arg name="car">
            <ref bean="car"></ref>
        </constructor-arg>
    </bean>
</beans>

测试

@Test
    public void test05() {
        //获取配置文件 beans.xml
        ApplicationContext context = new ClassPathXmlApplicationContext("beans.xml");
        //配置文件的bean  id
        Person person1 = context.getBean("persion", Person.class);
        Person person2 = context.getBean("persion", Person.class);
        Person person3 = context.getBean("persion", Person.class);
        System.out.println(person1==person2&&person1==person3);
    }

最后,测试test05()方法,控制台输出true,说明了默认情况下bean交给Spring容器管理之后,这个bean就是一个单实例(单例模式)的,即每次调用getBean()方法,获取到的都是同一个bean实例。

结果截图:

 

8.2prototype

每次从容器获取bean都是新的对象

实体类 测试都和singleton相同

beans.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" xmlns:p="http://www.springframework.org/schema/p"
       xmlns:util="http://www.springframework.org/schema/util"
​
       xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans.xsd">
<bean id="car" class="com.syf.bean.Car">
    <property name="brand" value="帕萨特"></property>
    <property name="corp" value="大众"></property>
    <property name="price" value="5000"></property>
</bean>
    <bean id="persion" class="com.syf.bean.Person"  scope="prototype">
        <constructor-arg name="car">
            <ref bean="car"></ref>
        </constructor-arg>
    </bean>
​
</beans>

结果截图为:

 

最后,测试test05()方法,控制台输出flase,就已经证实了若bean的作用域置为prototype,那么每次从Spring容器获取bean都将是新的对象。

9.Spring Bean 的生命周期

9.1 五步

1.构造方法

2.set方法

3.初始化方法

4.bean可以使用

5.销毁方法

BeanLife.java

package com.syf.bean;
​
public class BeanLife {
    public String name;
​
    public BeanLife() {
        System.out.println("无参调用了");
    }
​
    public void setName(String name) {
        this.name = name;
        System.out.println("Set方法执行了");
    }
​
    public String getName() {
        System.out.println("Get方法执行了");
        return name;
​
    }
​
    public void init(){
        System.out.println("init方法执行了");
    }
    public void dertory(){
        System.out.println("dertory方法执行了");
    }
}

bean.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="bean" class="com.syf.bean.BeanLife" init-method="init" destroy-method="dertory">
    <property name="name" value="李四"></property>
</bean>
</beans>

测试:

@Test
    public void test06() {
        //获取配置文件 beans.xml
        ClassPathXmlApplicationContext context = new ClassPathXmlApplicationContext("beans5.xml");
        System.out.println("-------加载配置文件-----------");
        //配置文件的bean  id
        BeanLife beanLife=context.getBean("bean",BeanLife.class);
        System.out.println("-----------Spring获取对象--------");
        context.close();
    }

结果截图:

 

七步:

1.构造方法

2.set方法

3.初始化之前执行

4.初始化方法

5.初始化之后执行

6.bean可以使用

7.销毁方法

新建BeanLife.java实现接口BeanPostProcessor 重写方法 postProcessBeforeInitialization和postProcessAfterInitialization

package com.syf.bean;
​

import org.springframework.beans.BeansException;
import org.springframework.beans.factory.config.BeanPostProcessor;
​
public class BeanLife2 implements BeanPostProcessor {
    @Override
    public Object postProcessBeforeInitialization(Object bean, String beanName) throws BeansException {
        System.out.println("初始化之前执行了");
        return BeanPostProcessor.super.postProcessBeforeInitialization(bean, beanName);
    }
​
    @Override
    public Object postProcessAfterInitialization(Object bean, String beanName) throws BeansException {
        System.out.println("初始化之后前执行了");
        return BeanPostProcessor.super.postProcessAfterInitialization(bean, beanName);
    }
}

bean5更改后:

<?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="bean" class="com.syf.bean.BeanLife" init-method="init" destroy-method="dertory">
    <property name="name" value="李四"></property>
</bean>
    <bean id="bean1" class="com.syf.bean.BeanLife2"></bean>
</beans>

测试和前面一致:

结果截图:

 

10.Spring的两种bean

普通bean:在配置文件中定义bean类型就是返回类型

工厂bean:在配置文件中定义bean类型可以与返回类型不一致 ,返回类型与实现接口式类型一致

10.1 普通bean

1.创建类

package com.syf.bean;
​
import lombok.AllArgsConstructor;
import lombok.Getter;
import lombok.NoArgsConstructor;
import lombok.Setter;
​
import java.util.List;
@Getter
@Setter
@NoArgsConstructor
@AllArgsConstructor
public class Dept {
    private Integer id;
    private String deptname;
    private List<Emp> list;
}

2.写bean.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" xmlns:util="http://www.springframework.org/schema/util"
       xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans.xsd">
<bean id="dept1" class="com.syf.bean.Dept">
    <constructor-arg name="id" value="002"></constructor-arg>
    <constructor-arg name="deptname" value="公益部"></constructor-arg>
​
​
​
</beans>

测试

@Test
    public void test03() {
        //获取配置文件 beans.xml
        ApplicationContext context = new ClassPathXmlApplicationContext("beans3.xml");
        //配置文件的bean  id
        Dept dept=context.getBean("dept",Dept.class);
        System.out.println(dept.getDeptname());
    }

10.2 工厂bean

1.创建类MyFactoryBean 实现接口FactoryBean

package com.syf.bean;
​
import org.springframework.beans.factory.FactoryBean;
​
public class MyFactoryBean implements FactoryBean<Dept> {
    @Override
    public Dept getObject() throws Exception {
        return null;
    }
​
    @Override
    public Class<?> getObjectType() {
        return null;
    }
}

2.bean写入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="myFactoryBean" class="com.syf.bean.MyFactoryBean"></bean>
</beans>

3.测试

    @Test
    public void test07() {
        //获取配置文件 beans.xml
        ApplicationContext context = new ClassPathXmlApplicationContext("beans6.xml");
        //配置文件的bean  id
        Object obj=context.getBean("myFactoryBean",Dept.class);
        System.out.println(obj);
    }

4.结果

 

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值