说一说Spring(1)

最近回头重新看了看spring来总结下吧

Spring是什么?
Spring是分层的 Java SE/EE应用 full-stack 轻量级开源框架,以 IoC(Inverse Of Control: 反转控制)和 AOP(Aspect Oriented Programming:面向切面编程)为内核,提供了展现层 Spring MVC 和持久层 Spring JDBC 以及业务层事务管理等众多的企业级应用技术,还能整合开源世界众多 著名的第三方框架和类库,逐渐成为使用最多的Java EE 企业应用开源框架。

Spring的优势

  1. 方便解耦,简化开发 :
    通过 Spring提供的 IoC容器,可以将对象间的依赖关系交由 Spring进行控制,避免硬编码所造 成的过度程序耦合。用户也不必再为单 例模式类、属性文件解析等这些很底层的需求编写代码,可 以更专注于上层的应用。
  2. AOP编程的支持 :通过 Spring的 AOP 功能,方便进行面向切面的编程,许多不容易用传统OOP 实现的功能可以通过 AOP 轻松应付。
  3. 声明式事务的支持 :可以将我们从单调烦闷的事务管理代码中解脱出来,通过声明式方式灵活的进行事务的管理, 提高开发效率和质量。

在这里插入图片描述

IoC 的概念和作用

IOC:控制反转(Inversion of Control) 将创建对象的权利交给框架,是框架的重要特征。消减程序的耦合性。

程序的耦合:
耦合性(Coupling),也叫耦合度,是对模块间关联程度的度量。耦合的强弱取决于模块间接口的复杂性、调 用模块的方式以及通过界面传送数据的多少。模块间的耦合度是指模块之间的依赖关系,包括控制关系、调用关系、数据传递关系。模块间联系越多,其耦合性越强,同时表明其独立性越差( 降低耦合性,可以提高其独立 性)。

可使用Spring的IOC解决程序的耦合:
1.基于 XML 的配置

<!-- bean 标签:用于配置让 spring 创建对象,并且存入 ioc 容器之中       id 属性:对象的唯一标识。       class 属性:指定要创建对象的全限定类名 --> 
<!-- 配置 service -->    
<bean id="accountService" class="com.itheima.service.impl.AccountServiceImpl"> </bean> 
<!-- 配置 dao --> 
<bean id="accountDao" class="com.itheima.dao.impl.AccountDaoImpl"></bean> 

测试是否注入:

public class Client {  /** 
      * 使用 main 方法获取容器测试执行 
      * /
          public static void main(String[] args) {   
          //1.使用 ApplicationContext 接口,就是在获取 spring 容器   
          ApplicationContext ac = new ClassPathXmlApplicationContext("bean.xml");   
          //2.根据 bean 的 id 获取对象   
          IAccountService aService = (IAccountService) ac.getBean("accountService");   
          System.out.println(aService);   
           IAccountDao aDao = (IAccountDao) ac.getBean("accountDao");   
           System.out.println(aDao);  
           } 
           } 

在这里插入图片描述

BeanFactory和 ApplicationContext 的区别
在这里插入图片描述
BeanFactory 才是 Spring 容器中的顶层接口。 ApplicationContext 是它的子接口。 BeanFactory 和 ApplicationContext 的区别:
创建对象的时间点不一样。 ApplicationContext:只要一读取配置文件,默认情况下就会创建对象。
BeanFactory:什么使用什么时候创建对象。

ApplicationContext 接口的实现类
ClassPathXmlApplicationContext: 它是从类的根路径下加载配置文件 推荐使用这种
FileSystemXmlApplicationContext: 它是从磁盘路径上加载配置文件,配置文件可以在磁盘的任意位置。 AnnotationConfigApplicationContext: 当我们使用注解配置容器对象时,需要使用此类来创建 spring 容器。它用来读取注解。

bean标签
作用: 用于配置对象让 spring 来创建的。 默认情况下它调用的是类中的无参构造函数。如果没有无参构造函数则不能创建成功。
属性: id:给对象在容器中提供一个唯一标识。用于获取对象。
class:指定类的全限定类名。用于反射创建对象。默认情况下调用无参构造函数。
scope:指定对象的作用范围。 * singleton :默认值,单例的. * prototype :多例的. * request :WEB 项目中,Spring 创建一个 Bean 的对象,将对象存入到 request 域中. * session :WEB 项目中,Spring 创建一个 Bean 的对象,将对象存入到 session 域中. * global session:WEB 项目中,应用在 Portlet 环境.如果没有 Portlet 环境那么 globalSession 相当于 session.
init-method:指定类中的初始化方法名称。 destroy-method:指定类中销毁方法名称。

单例对象:scope=“singleton” 一个应用只有一个对象的实例。它的作用范围就是整个引用。
生命周期:对象出生:当应用加载,创建容器时,对象就被创建了。对象活着:只要容器在,对象一直活着。 对象死亡:当应用卸载,销毁容器时,对象就被销毁了。
多例对象:scope=“prototype” 每次访问对象时,都会重新创建对象实例。生命周期:对象出生:当使用对象时,创建新的对象实例。 对象活着:只要对象在使用中,就一直活着。 对象死亡:当对象长时间不用时,被 java 的垃圾回收器回收了。

实例化Bean的三种方式:
第一种方式:使用默认无参构造函数
<–在默认情况下: 它会根据默认无参构造函数来创建类对象。如果 bean 中没有默认无参构造函数,将会创建失败–>

第二种方式:spring管理静态工厂-使用静态工厂的方法创建对象

/** 
 * 模拟一个静态工厂,创建业务层实现类  */ 
        public class StaticFactory {   
                    public static IAccountService createAccountService(){   return new AccountServiceImpl();  } 
                    }

<!-- 此种方式是:   使用 StaticFactory 类中的静态方法 createAccountService 创建对象,并存入 spring 容器   id 属性:指定 bean 的 id,用于从容器中获取   class 属性:指定静态工厂的全限定类名   factory-method 属性:指定生产对象的静态方法  -->

<bean id="accountService"  class="com.itheima.factory.StaticFactory"     factory-method="createAccountService"></bean>

第三种方式:spring管理实例工厂-使用实例工厂的方法创建对象

/** 
 * 模拟一个实例工厂,创建业务层实现类  * 此工厂创建对象,必须现有工厂实例对象,再调用方法  */ 
                  public class InstanceFactory {   
                  public IAccountService createAccountService(){   return new AccountServiceImpl();  } 
                  }

<!-- 此种方式是:    先把工厂的创建交给 spring 来管理。   然后在使用工厂的 bean 来调用里面的方法   factory-bean 属性:用于指定实例工厂 bean 的 id。   factory-method 属性:用于指定实例工厂中创建对象的方法。  -->
<bean id="instancFactory" class="com.itheima.factory.InstanceFactory"></bean>  
<bean id="accountService"      factory-bean="instancFactory"      factory-method="createAccountService"></bean>

spring 的依赖注入
依赖注入:Dependency Injection。它是 spring 框架核心 ioc 的具体实现。 我们的程序在编写时,通过控制反转,把对象的创建交给了 spring,但是代码中不可能出现没有依赖的情况。 ioc 解耦只是降低他们的依赖关系,但不会消除。例如:我们的业务层仍会调用持久层的方法。

1.构造函数注入:
顾名思义,就是使用类中的构造函数,给成员变量赋值。注意,赋值的操作不是我们自己做的,而是通过配置
的方式,让 spring 框架来为我们注入。


public AccountServiceImpl(String name, Integer age, Date birthday) {   this.name = name;   this.age = age;   this.birthday = birthday;  }

<--index:指定参数在构造函数参数列表的索引位置     type:指定参数在构造函数中的数据类型   name:指定参数在构造函数中的名称  
value:它能赋的值是基本数据类型和 String 类型     ref:它能赋的值是其他 bean 类型,也就是说,必须得是在配置文件中配置过的 bean  -->

<bean id="accountService" class="com.itheima.service.impl.AccountServiceImpl"> 
 <constructor-arg name="name" value=" 张三 "></constructor-arg>  
 <constructor-arg name="age" value="18"></constructor-arg> 
 <constructor-arg name="birthday" ref="now"></constructor-arg> 
 </bean>
 <bean id="now" class="java.util.Date"></bean> 

2.Set方法注入:
顾名思义,就是在类中提供需要注入成员的 set 方法.。

name:找的是类中 set 方法后面的部分    ref:给属性赋值是其他 bean 类型的    value:给属性赋值是基本数据类型和 string 类型

<bean id="accountService" class="com.itheima.service.impl.AccountServiceImpl">   
<property name="name" value="test"></property> 
 <property name="age" value="21"></property>   
 <property name="birthday" ref="now"></property> 
</bean> <bean id="now" class="java.util.Date"></bean> 

3.使用 p 名称空间注入数据(本质还是调用 set 方法)
此种方式是通过在 xml中导入 p名称空间,使用 p:propertyName 来注入数据,它的本质仍然是调用类中的 set 方法实现注入功能。

<beans xmlns="http://www.springframework.org/schema/beans" 
     xmlns:p="http://www.springframework.org/schema/p" 
      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="accountService"  
    class="com.itheima.service.impl.AccountServiceImpl4"     p:name="test" p:age="21" p:birthday-ref="now"/> </beans> 

注入集合属性:

<!-- 注入集合数据    List 结构的:   array,list,set 
 Map 结构的   map,entry,props,prop 
--> 
<bean id="accountService" class="com.itheima.service.impl.AccountServiceImpl"> 
 <!-- 在注入集合数据时,只要结构相同,标签可以互换 -->  
 <!-- 给数组注入数据 -->  
 <property name="myStrs"> 
   <array>    
       <value>AAA</value>    
        <value>BBB</value>    
        <value>CCC</value>  
   </array> 
 </property> 
 
 <!-- 注入 list 集合数据 -->  
 <property name="myList">   
          <list>    
                <value>AAA</value>    
                <value>BBB</value>    
                <value>CCC</value>   
            </list>  
 </property> 
 
 <!-- 注入 set 集合数据 -->  
 <property name="mySet"> 
              <set>    
                      <value>AAA</value>    
                      <value>BBB</value>    
                      <value>CCC</value>   
               </set>  
   </property> 
   
 <!-- 注入 Map 数据 -->  
 <property name="myMap">
            <map>    
                <entry key="testA" value="aaa"></entry> 
               <entry key="testB">     
                 <value>bbb</value> </entry>   
            </map>     
 </property> 
 
 <!-- 注入 properties 数据 --> 
 <property name="myProps"> 
         <props> 
             <prop key="testA">aaa</prop>    
            <prop key="testB">bbb</prop>   
         </props> 
    </property> 
</bean>

IOC常用注解配置

用于创建对象的:相当于:

@Component
作用: 把资源让 spring 来管理。相当于在 xml 中配置一个 bean。
属性: value:指定 bean 的 id。如果不指定 value 属性,默认 bean 的 id 是当前类的类名。首字母小写

@Controller @Service @Repository
他们三个注解都是针对一个的衍生注解,他们的作用及属性都是一模一样的。 他们只不过是提供了更加明确的语义化。
@Controller:一般用于表现层的注解。 @Service:一般用于业务层的注解。 @Repository:一般用于持久层的注解。
细节:如果注解中有且只有一个属性要赋值时,且名称是 value,value在赋值是可以不写。

用于注入数据的
相当于:

@Autowired : 作用: 自动按照类型注入。当使用注解注入属性时,set方法可以省略。它只能注入其他 bean 类型。当有多个 类型匹配时,使用要注入的对象变量名称作为 bean 的 id,在 spring 容器查找,找到了也可以注入成功。找不到 就报错。

@Qualifier : 作用: 在自动按照类型注入的基础之上,再按照 Bean 的 id 注入。它在给字段注入时不能独立使用,必须和 @Autowire 一起使用;但是给方法参数注入时,可以独立使用。 属性: value:指定 bean 的 id。

@Resource: 作用: 直接按照 Bean 的 id 注入。它也只能注入其他 bean 类型。 属性: name:指定 bean 的 id。

@Value : 作用: 注入基本数据类型和 String 类型数据的 属性: value:用于指定值 。

用于改变作用范围的
相当于:
@Scope: 作用: 指定 bean 的作用范围。 属性: value:指定范围的值。 取值:singleton prototype request session globalsession

和生命周期相关的:(了解)
相当于:
@PostConstruct :作用: 用于指定初始化方法。
@PreDestroy :作用: 用于指定销毁方法。

注解的优势: 配置简单,维护方便(我们找到类,就相当于找到了对应的配置)。
XML 的优势: 修改时,不用改源码。不涉及重新编译和部署。

有关Spring的配置注解:

@Configuration: 作用: 用于指定当前类是一个 spring 配置类,当创建容器时会从该类上加载注解。获取容器时需要使用 AnnotationApplicationContext(有@Configuration 注解的类.class)。 属性: value:用于指定配置类的字节码

@ComponentScan : 作用: 用于指定 spring 在初始化容器时要扫描的包。作用和在 spring 的 xml 配置文件中的: <context:component-scan base-package=“com.itheima”/>是一样的。 属性: basePackages:用于指定要扫描的包。和该注解中的 value 属性作用一样。

@Bean :作用: 该注解只能写在方法上,表明使用此方法创建一个对象,并且放入 spring 容器。 属性: name:给当前@Bean 注解方法创建的对象指定一个名称(即 bean 的 id)。

@PropertySource : 作用: 用于加载.properties 文件中的配置。例如我们配置数据源时,可以把连接数据库的信息写到 properties 配置文件中,就可以使用此注解指定 properties 配置文件的位置。 属性: value[]:用于指定 properties 文件位置。如果是在类路径下,需要写上 classpath:

@Import: 作用: 用于导入其他配置类,在引入其他配置类时,可以不用再写@Configuration 注解。当然,写上也没问 题。 属性: value[]:用于指定其他配置类的字节码。
实例代码

            @Configuration 
            @ComponentScan(basePackages = "com.spring") 
            @Import({ JdbcConfig.class}) 
            public class SpringConfiguration { 
            }

            @Configuration 
            @PropertySource("classpath:jdbc.properties") 
            public class JdbcConfig{ 
            }

Spring 整合 Junit

导入相对应的包后

第一步:
使用@RunWith 注解替换原有运行器

第二步:
使用@ContextConfiguration 指定 spring 配置文件的位置

第三步:
使用@Autowired 给测试类中的变量注入数据

                      @RunWith(SpringJUnit4ClassRunner.class) 
                      @ContextConfiguration(locations= {"classpath:bean.xml"}) 
                       public class AccountServiceTest {    
                       @Autowired 
                       private IAccountService as ; 
                       }
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值