如何理解spring框架

发布时间:2021-10-20 17:43:00 作者:柒染
来源:亿速云 阅读:164

如何理解spring框架,很多新手对此不是很清楚,为了帮助大家解决这个难题,下面小编将为大家详细讲解,有这方面需求的人可以来学习下,希望你能有所收获。

spring:分层的JavaSE/EE应用full-stack轻量级开源框架,以Ioc(反转控制)和AOP(面相切面编程)为内核,提供了展现层springMVC和持久层spring JDBC以及业务层事务管理等众多的企业级应用技术,还能整合开源世界众多著名的第三方框架和类库,逐渐成为使用最多的JavaEE企业应用开源框架。

优势:

1、方便解耦,简化开发

2、AOP编程的支持

3、声明式事务的支持

4、方便程序的测试

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

6、降低JavaEE的使用难度

7、源码的经典的学习范例

程序的耦合:程序键的依赖关系,包括类之间的依赖,方法间的依赖。

解耦:降低程序间的依赖关系

实际开发中应该做到,编译期不依赖,运行时才依赖

解决思路:

第一步:使用反射来创建对象,而避免使用new关键字

第二步:通过读取配置文件来获取要创建的对象全限定类名。

Ioc:

概念:控制反转,把创建对象的权利交给框架,是框架的重要特征,并非面向对象的专用术语。它包括依赖注入和依赖查找。

作用:削减计算机程序的耦合,解除我们代码中的依赖关系。

使用:

1、配置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
        https://www.springframework.org/schema/beans/spring-beans.xsd">

    <bean id="accountDao" class="lianbang.wu.dao.Impl.AccountDaoImpl"></bean>
    <bean id="accountService" class="lianbang.wu.service.Impl.AccountServiceImpl"></bean>
</beans>

2、获取ioc核心容器,并且根据id获取对象

ApplicationContext ac = new ClassPathXmlApplicationContext("Bean.xml");
IAccountDao accountDao = ac.getBean("accountDao",IAccountDao.class);
IAccountService accountService = ac.getBean("accountService",IAccountService.class);

ApplicationContext的三个常用实现类:

1、ClassPathXmlApplicationContext:它可以加载类路径下的配置文件,要求配置文件必须在类路径下,不在的话,加载不了

2、FileSystemXmlApplicationContext:它可以加载磁盘任意路径下的配置文件,前提是有访问权限

3、AnnotationConfigApplicationContext:它是用于读取注解创建容器的。

ApplicationContext:它在构建核心容器时,创建对象采用的策略是采用立即加载的方式,也就是说,只要一读取完配置文件马上就创建配置文件中配置的对象,适用单例对象

BeanFactory:它在构建核心容器时,创建对象采用的策略是采用延迟加载的方式,也就是说,什么时候根据id获取对象了,什么时候才真正的创建对象,适用多例对象

创建Bean的三种方式:

第一种:使用默认构造函数创建

<bean id="accountDao" class="lianbang.wu.dao.Impl.AccountDaoImpl"></bean>

注意:如果类中没有默认构造函数,则对象无法创建

第二种:使用普通工厂类中的方法创建对象(使用某个类中的方法创建对象,并存入spring容器)

<bean id="instanceFactory" class="lianbang.wu.factory.InstanceFactory"></bean>
<bean id="accountService" factory-bean="instanceFactory" factory-method="getAccountService"></bean>

第三种:使用工厂中的静态方法创建对象(使用某个类中的静态方法创建对象,并存入spring容器)

<bean id="accountService" class="lianbang.wu.factory.StaticFactory" factory-method="getAccountService"></bean>

Bean的作用范围调整:

bean标签的scope属性

作用:用于指定bean的作用范围

取值:

singleton:单例,默认值

prototype:多例的

request:作用于web应用的请求范围

session:作用于web应用的会话范围

global-session:作用于集群环境的会话范围,当不是集群时,它就是session

<bean id="product" class="lianbang.wu.domain.Product" scope="singleton"></bean>

Bean的生命周期

单例对象

出生:当容器创建时,对象出生

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

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

多例对象

出生:当我们使用对象时,创建

活着:对象只要在使用过程中就一直活着

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

spring的依赖注入:

作用:维护依赖关系

能注入的数据:

1、基本类型和String

2、其他bean类型(在配置文件中或者注解配置过的bean)

3、复杂类型/集合类型

注入的方式:

1、使用构造函数提供

在bean标签的内部,使用标签constructor-arg

标签中的属性:

type:用于指定要注入的数据的数据类型,该数据类型也是构造函数中某个或某些参数的类型

index:用于指定要注入的数据给构造函数中指定索引位置的参数赋值,索引的位置从0开始

name:用于指定给构造函数中指定名称的参数赋值

value:用于提供基本类型和string类型的数据

ref:用于指定其他bean类型数据,它指的就是在spring的Ioc核心容器中出现过的bean对象

</bean>
<bean id="accountService" class="lianbang.wu.service.Impl.AccountServiceImpl">
    <constructor-arg name="name" value="读者"></constructor-arg>
    <constructor-arg name="age" value="18"></constructor-arg>
    <constructor-arg name="birthday" value="now"></constructor-arg>
</bean>
<bean id="now" class="java.util.Date"></bean>

好处:在获取bean对象时,注入数据是必须的操作,否则对象无法创建成功

坏处:改变了bean对象的实例化方式,使我们在创建对象时,如果用不到这些数据也必须提供。

2、使用set方法提供

在bean标签的内部,使用property

标签的属性:

name:用于指定注入时所调用的set方法名称

value:用于提供基本类型和String类型的数据

ref:用于指定其他的bean类型数据。它指的就是在spring的Ioc容器中出现过的bean对象

</bean>
<bean id="accountService" class="lianbang.wu.service.Impl.AccountServiceImpl">
   <property name="name" value="读者"></property>
    <property name="age" value="18"></property>
    <property name="birthday" value="now"></property>
</bean>
<bean id="now" class="java.util.Date"></bean>

好处:创建对象时没有明确的限制,可以直接使用默认构造函数

坏处:如果有某个成员必须有值,则获取对象是有可能set方法没有执行

3、使用注解提供

复杂类型注入(集合,数组,propertise)

1、array,list,set

</bean>
<bean id="accountService" class="lianbang.wu.service.Impl.AccountServiceImpl">
    <property name="name">
        <array>aaa</array>
        <array>bbb</array>
        <array>ccc</array>
    </property>
</bean>

注意:只需将property标签下对应的子标签改变成对应的类型

2、map

<bean id="accountService" class="lianbang.wu.service.Impl.AccountServiceImpl">
    <property name="name">
       <map>
           <entry key="读者1" value="作品1"></entry>
           <entry key="读者2" value="作品2"></entry>
       </map>
    </property>
</bean>

3、properties

<bean id="accountService" class="lianbang.wu.service.Impl.AccountServiceImpl">
    <property name="name">
      <props>
          <prop key="读者1">作品1</prop>
      </props>
    </property>
</bean>

常见的Ioc注解:

注意,使用注解配置时,先要修改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:context="http://www.springframework.org/schema/context"
       xsi:schemaLocation="http://www.springframework.org/schema/beans
        https://www.springframework.org/schema/beans/spring-beans.xsd
        http://www.springframework.org/schema/context
        https://www.springframework.org/schema/context/spring-context.xsd">

    <context:annotation-config/>
    
    <context:component-scan base-package="lianbang.wu"></context:component-scan>

</beans>

1、用于创建对象的:作用就和xml配置文件中bean标签实现的功能一样

@Component

作用:把当前类对象存入spring容器中

属性:value:用于指定bean的id,当我们不写时,默认值是当前类名,首字母小写

@Controller:一般用在表现层

@Service:一般用在业务层

@Repository:一般用在持久层

以上三个注解他们的作用和属性于Conponent是一样的,只是为我们提供明确的三层使用的注解,使我们的三层对象更加清晰。

2、用于注入数据的:作用就和xml配置文件中property标签实现的功能一样

@Autowired

作用;自动按照类型注入,只要容器中有唯一一个bean对象类型和要注入的变量类型匹配,就可以注入成功。如果Ioc容器中没有任何bean类型和要注入的变量类型匹配,则报错,如果Ioc容器中有多个类型匹配,根据变量名称再去匹配Ioc容器中对应类型的Id名称

出现位置:可以在变量上,也可以是方法上

细节:在使用注解注入时,set方法就不是必须的了

@Qualifier

作用:按照类中注入的基础上再按照名称注入,它在给类成员注入时不能单独使用必须与Autowired配合使用,但是在给方法参数注入时可以

属性:value:用于指定注入bean的id。

@Resource

作用:直接按照bean的id注入,它可以单独使用

属性:name:用于指定bean的id

@value

作用:用于注入基本数据类型和String类型的数据

属性:value:用于指定数据的值,它可以使用spring中时spEl

spEl的写法:#{表达式}

3、用于改变作用范围:作用就和在bean标签中使用scope属性实现的功能一样

@Scope

作用:用于指定bean的作用范围

属性:value:指定范围的取值。常用:singleton(默认),prototype

4、和生命周期相关:作用就和bean标准中使用init-method和destroy-method的作用一样

@PreDestroy

作用:用于指定销毁方法

@PostConstruct

作用:用于指定初始化方法

Ioc的其他注解:

@Configuration

作用:当前类是一个配置类

@ConponentScan

作用:用于通过注解指定spring在创建容器时要扫描的包

属性:value:它和basePackages的作用是一样的,都是用于指定创建容器时要扫描的包。

@Bean

作用:用于把当前方法的返回值作为bean对象,存入spring的ioc容器中

属性:name:用于指定Bean的id,默认值是当前方法的名称

注意:当使用注解配置方法,如果方法有参数,spring框架会去容器中查找有没有可用bean对象,和Autowired机制一样。

使用注解配置类:

ApplicationContext ac = new AnnotationConfigApplicationContext(springConfig.class);

@import

作用:用于导入其他配置类

@propertySource

作用:用于指定properties文件的位置

属性:value,指定文件的名称和路径,classpath,表示类路径下

Spring整合Junit

第一步:导入spring整合Junit的jar包

第二步:使用Junit提供的一个注解把原有的main方法替换成spring提供的

@Runwith

第三步:告知spring的运行器,spring的ioc创建是基于xml还是注解的,并且说明位置

@ContextConfiguration

location:指定xml文件的位置,加上classpath关键字,表示在类路径下

classes:指定注解类所在的位置

注意:当我们使用spring 5.X版本的时候,要求Junit的jar必须是4.12以上

AOP:

概念:面向切面编程,它就是把完美程序重复的代码抽取出来,在需要执行的时候,使用动态代理技术,在不修改源码的基础上,对完美的已有方法进行增强。

相关术语:

Joinpoint:连接点:简单的说就是可以被增强的方法

Pointcut:切入点:简单的说就是被增强了的方法

Advice:通知:拦截到joinpoint之后所要做的事情,通知的类型:前置通知,后置通知,异常通知,最终通知,环绕通知。

Introduction:引介:是一种特殊的通知,在不修改代码的前提下,可以在运行期为类动态的添加一些方法。

Target:目标对象:被代理对象

Weaving:把增强应用到目标对象来创建新的代理对象的过程

Proxy:代理:一个类被AOP织入增强后,就产生一个结果代理类

Aspect:切面:切入点和通知的结合

基于XML方式:

1、把切面添加到Ioc容器

<bean id="logger" class="lianbang.wu.utils.Logger"></bean>

2、使用aop:config标签表明开始AOP的配置

3、使用aop:aspect标签表明配置切面

      id:给切面提供一个唯一标识

      ref:是指定通知类bean的id

4、在aop:aspect标签的内部使用对应标签来配置通知的类型

      aop:before:表示配置前置通知,在切入点方法执行之前执行

            method:指定logger类中哪个方法是前置通知

            pointcut:用于指定切入点表达式,该表达式的含义指的是对业务层中哪些方法增强

           切入点表达式的写法:execution(表达式)

           表达式:访问修饰符 返回值 包名.类名.方法名(参数列表)

           全通配写法 * *..*.*(..)

           实际开发通常写法:* 包名.*.*(..)

      aop:after-returning:后置通知,在切入点方法执行之后执行

      aop:after-throwing:异常通知,在切入点执行产生异常之后执行

      aop:after:最终通知,无论切入点方法是否正常执行,它都会在后面执行

      aop:around:环绕配置,当配置环绕通知之后,需要在切入点方法中传入参数,明确调用切入点等等

<aop:config>
        <aop:aspect id="logAdvice" ref="logger">
            <aop:before method="printLog" pointcut="execution(public void lianbang.wu.service.Impl.AccountServiceImpl.saveAccount())"></aop:before>
        </aop:aspect>
    </aop:config>
</beans>

基于注解方式:

@Component("logger")
@Aspect
//@EnableAspectJAutoProxy
public class Logger {

    @Pointcut("execution(* lianbang.wu.service.Impl.*.*(..))")
    private void pt1(){};

    @Before("pt1()")
    public void printLog(){
        System.out.println("Logger类中的方法开始记录日志。。。");
    }

注意:环绕通知必须传入ProceedingJoinPoint类型参数

@Around("pt1()")
public void around(ProceedingJoinPoint joinPoint){
    System.out.println("前置通知");
    try {
        joinPoint.proceed();
    } catch (Throwable throwable) {
        throwable.printStackTrace();
    }
    System.out.println("后置通知");
}

jdbcTemplate

作用:用于和数据库交互,实现对表的CRUD操作

public class JdbcTemplateDemo  {
    public static void main(String[] args) {
        //0、准备数据源
        DriverManagerDataSource driverManagerDataSource = new DriverManagerDataSource();
        driverManagerDataSource.setDriverClassName("com.mysql.jdbc.Driver");
        driverManagerDataSource.setUrl("jdbc:mysql://localhost:3306/eesy");
        driverManagerDataSource.setUsername("root");
        driverManagerDataSource.setPassword("120609");
        //1、创建对象
        JdbcTemplate jdbcTemplate = new JdbcTemplate();
        jdbcTemplate.setDataSource(driverManagerDataSource);
        //2、执行操作
        jdbcTemplate.execute("insert into account(id,uid,money)value (5,46,1000)");
    }
}

补充:可以将上面2个new出来的对象放入Ioc对象,在进行调用

看完上述内容是否对您有帮助呢?如果还想对相关知识有进一步的了解或阅读更多相关文章,请关注亿速云行业资讯频道,感谢您对亿速云的支持。

推荐阅读:
  1. Spring框架是什么
  2. Spring框架AOP的使用及个人对底层原理的理解

免责声明:本站发布的内容(图片、视频和文字)以原创、转载和分享为主,文章观点不代表本网站立场,如果涉及侵权请联系站长邮箱:is@yisu.com进行举报,并提供相关证据,一经查实,将立刻删除涉嫌侵权内容。

spring

上一篇:go-web程序的热更新是什么呢

下一篇:Java和Docker限制的事有哪些

相关阅读

您好,登录后才能下订单哦!

密码登录
登录注册
其他方式登录
点击 登录注册 即表示同意《亿速云用户服务条款》