Spring入门概述及基本知识点

Spring是什么:

我们常说的Spring,其实在官网中全称是SpringFrameWork。

Spring是一个轻量级,非入侵式的Java开发框架(主要用于业务层,和整合其他层),解决了业务层和表现层、持久层的耦合问题,将面向接口编程贯穿整个框架,解决了企业级应用的复杂性,使JavaWeb的开发更加简单。

Spring开发方式:

Spring的核心是控制反转(IOC)和面向切面编程(AOP)

Spring通过控制反转和依赖注入(DI)可以很好的对程序进行解耦,通过配置文件(applicationContext.xml)或注解的方式对类进行管理。通过Spring面向切面的编程方式,可以对指定代码进行增强。

使用Maven工程构建,pom文件需要的基础坐标依赖:

<dependencies>
		<!--maven传递依赖,导入依赖jar包:包括spring核心依赖包:spring-core、spring-beans、spring-aop等-->
        <dependency>
            <groupId>org.springframework</groupId>
            <artifactId>spring-context</artifactId>
            <version>5.0.2.RELEASE</version>
        </dependency>

        <dependency>
            <groupId>junit</groupId>
            <artifactId>junit</artifactId>
            <version>4.12</version>
            <scope>test</scope>
        </dependency>

        <!--Spring框架整合JUnit单元测试,必须先有Junit单元测试的环境-->
        <dependency>
            <groupId>org.springframework</groupId>
            <artifactId>spring-test</artifactId>
            <version>5.0.2.RELEASE</version>
            <scope>test</scope>
        </dependency>

        <!-- AOP联盟 -->
        <dependency>
            <groupId>aopalliance</groupId>
            <artifactId>aopalliance</artifactId>
            <version>1.0</version>
        </dependency>
        <!-- Spring Aspects -->
        <dependency>
            <groupId>org.springframework</groupId>
            <artifactId>spring-aspects</artifactId>
            <version>5.0.2.RELEASE</version>
        </dependency>
        <!-- aspectj -->
        <dependency>
                <groupId>org.aspectj</groupId>
            <artifactId>aspectjweaver</artifactId>
            <version>1.8.3</version>
        </dependency>
        
        <!--Spring事务管理相关-->
        <dependency>
            <groupId>org.springframework</groupId>
            <artifactId>spring-tx</artifactId>
            <version>5.0.2.RELEASE</version>
        </dependency>

</dependencies> 

什么是IoC(Inversion of Control,控制反转):

IoC是一种设计思想,将对象的创建权利(new)反转(交给)Spring框架,解决程序耦合度过高的问题。即原来是程序主动创建对象,控制权在我们手上;现在由Spring创建,管理,注入对象,控制权在Spring手上。

回想一下,之前我们在service层,经常会出现这样的代码:

public class OrderServiceImpl implements OrderService {

    //持久层对象,直接在程序中创建对象
    private OrderDao orderDao = new OrderDaoImpl();
	
	//其他逻辑
}

如果我们的业务在后续发生变化,业务层调用持久层的实现类发生变动,那么有关new OrderDaoImpl()的程序,要全部发生变化,虽然在这个例子中改变并不明显,但在真正的企业级应用开发中,牵一发而动全身,由于项目大且复杂,修改相关代码是一件吃力且昂贵的事情。

那么现在我们修改一下代码:

public class OrderServiceImpl implements OrderService {

    //持久层对象,直接在程序中创建对象
    private OrderDao orderDao;
	
	//利用set方法,动态实现对象的赋值。
	public void setOrderDao(OrderDao orderDao){
		this.orderDao = orderDao;
	}
	
	//其他逻辑
}

其实仅仅是一个set方法,就发生了革命性的变化。使用set方法后,对象不在由程序主动创建,而是成为了被动接受的对象。主动权给了调用者,即我们只需要改动传入对象的代码即可。

这种思想,使开发人员不用再主动去管理对象的创建,使系统耦合性大大降低,这种逻辑就是IOC的底层原理。

什么是DI(Dependency Injection,依赖注入):

Sprig的IoC需要DI,在Spring负责创建Bean对象时,动态的将其依赖的对象注入到Bean对象中。

Spring最核心的依赖注入,本质就是用set方法注入。使用bean标签下的property。

我们原来的业务逻辑:

在这里插入图片描述
SpringIoC的业务逻辑:

在这里插入图片描述
在这里插入图片描述

Spring配置文件开发

Spring框架在初始化时先读取配置文件,来决定管理哪些类,把哪些对象注入到另外的对象中去。

Spring配置文件命名格式:applicationContext.xml,使用schema约束。

Spring配置文件通过bean标签管理对象(自定义的类,Spring框架的类),交给IOC容器。

使用配置文件后,我们就只需要在配置文件中修改相关bean,即可解决上面所阐述耦合度问题。

Spring配置文件的主要内容:

<?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">

    <!--把UserServiceImpl类交给IoC容器进行管理,对象由IoC容器来创建,bean标签管理

        id:对象在IoC容器唯一的名称
        class:管理类的全路径(底层通过反射创建对象)
        scope:创建对象的生命周期(作用域)
            singleton(单例,加载配置文件,就会创建实例,且IOC容器只存在该类一个实例。生命周期和容器生命周期一致)  开发中大部分都是这个模式
            prototype(多例,每次从IOC容器中获取对象时,才会创建一个实例。容器不负责销毁对象,由GC销毁)
            request(多例,每次请求都会创建一个实例,存到request域对象,生命周期为一次请求)
            session(多例,每次会话都会创建一个实例,存到session域对象,生命周期为一次会话)
        init-method:当加载bean,创建对象后,调用init-method属性指定的方法
        destroy-method,当bean从容器中删除时,调用destroy-method属性指定的方法
    -->

    <!--实例化bean的三种方式,第一种最常用-->
    <!--1.默认调用无参构造构造器实例化对象-->

    <bean id="usImpl" class="cn.cx.service.UserServiceImpl" scope="singleton" init-method="init" destroy-method="destroy"/>

    <!--2.静态工厂方式实例化对象,class写我们自定义的静态工厂类,factory-method写该类里的静态方法,返回一个我们需要的实例对象
    <bean id="usImpl" class="xx.xx.xx.StaticFactory" factory-method="method"/>
    -->

    <!--3.动态工厂方式实例化对象,先配置一个bean,定义id和类的全路径,然后再配置一个bean,factory-bean:自定义的动态工厂,factory-method该类中的方法,返回一个我们需要的实例对象
    <bean id="dfactory" class="xx.xx.xx.Dfactory"/>
    <bean id="usImpl" factory-bean="dfactory" factory-method="method"/>
    -->

    <!--DI:属性的依赖注入-->
    <!--
        之前的方式:UserServiceImpl usImpl = new UserServiceImpl();
        现在创建对象,并给对象赋值由Spring完成。
        id相当于变量名,class相当于对象类型,property相当于对象,其中的name相当于属性名,value相当于属性值
        底层用set方法实现
        要想实现Bean的自动装配,要在bean标签加上autowire属性,常用的值类型有byName和byType
    -->
    <bean id="osImpl" class="cn.cx.service.OrderServiceImpl">
        <!--将odImpl注入到osImpl的orderDao属性上,引用数据类型用ref-->
        <property name="orderDao" ref="odImpl"/>
        <!--普通数据类型用value-->
        <property name="username" value="lisichen"/>
        <property name="size" value="45"/>
    </bean>

    <!--DI:构造器的依赖注入-->
    <bean id="osImpl1" class="cn.cx.service.OrderServiceImpl1">
        <constructor-arg name="orderDao" ref="odImpl"/>
        <constructor-arg name="username" value="duansl"/>
        <constructor-arg name="size" value="78"/>
    </bean>

    <bean id="odImpl" class="cn.cx.dao.OrderDaoImpl"></bean>

    <!--DI:数组,集合,Properties的依赖注入-->
    <bean id="cb" class="cn.cx.demo.CollectionBean">
        <property name="strs">
            <array>
                <value>断舍离</value>
                <value>立思辰</value>
                <value>王思傲</value>
            </array>
        </property>

        <property name="list">
            <list>
                <value>计算机</value>
                <value>互联网</value>
                <value>电商</value>
            </list>
        </property>

        <property name="map">
            <map>
                <!--如果是引用类型,加-ref-->
                <entry key="1" value="a"/>
                <entry key="2" value="b"/>
                <entry key="3" value="c"/>
            </map>
        </property>

        <property name="prop">
            <props>
                <prop key="username">root</prop>
                <prop key="password">adssd</prop>
            </props>
        </property>
    </bean>

    <!--可以引入其他加载文件,多人开发时使用
    <import resource="xxxx.xml"/>
    -->
</beans>

调用对象的逻辑:

public class Test {

    /**
     * 我们第一开始管理对象的方式:由我创建
     * */
    @org.junit.Test
    public void test(){
        UserService us = new UserServiceImpl();
        us.hello();
    }

    /**
     * 使用IoC方式管理对象:交给SpringIoC创建
     * */
    @org.junit.Test
    public void testIoc(){
        //创建SpringIoc的工厂(Spring上下文对象),加载applicationContext.xml配置文件,将配置文件中指定的类创建成对象,存入IOC容器中
        ApplicationContext ac = new ClassPathXmlApplicationContext("applicationContext.xml");
        /*可以以可变参数形式,加载多个配置文件
        ApplicationContext ac = new ClassPathXmlApplicationContext("applicationContext.xml","xxx.xml","xxxx.xml");*/
        System.out.println("=================");
        //从容器中获取对象(底层是一个Map集合),传入参数是配置文件中对应类的id值
        UserService usImpl = (UserService) ac.getBean("usImpl");
        usImpl.hello();
    }
}

Spring注解开发:

想使用注解,需要在Spring配置文件中引入相关schem约束的名称空间,并开启注解扫描:

<?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 http://www.springframework.org/schema/beans/spring-beans.xsd
        http://www.springframework.org/schema/context http://www.springframework.org/schema/context/spring-context.xsd">
        
    <!--开启注解扫描 cn.cx.所有的包中的所有的类 -->
    <context:component-scan base-package="cn.cx"/>

</beans>

之后想要将哪个类交给IOC容器管理,就在哪个类上加上对应注解。

IOC管理常用注解:

@Component:把注解的类加入IOC容器管理,在非三层类上使用。
@Repository:作用同@Component,在持久层使用。
@Service:作用同@Component,在业务层使用。
@Controller:作用同@Component,在控制层使用。

DI常用注解(实现Bean的自动装配):

@Value:用于注入普通类型(String,int,Double等)
@Autowired:用于注入引用类型,默认按类型进行自动装配(byType),使用后可以省略对应的set方法,如果进行注解的类没有加上IoC管理的注解,编辑器会报错
@Qualifier:强制按id名称注入,不能单独使用,要与@Autowired一起使用
@Resource:Java的原生注解,也可以实现自动装配,默认通过byName查找,如果匹配不到,再通过byType查找

替换扫描包的注解:

@Configuration:声明当前类为配置类
@ComponentScan:扫描指定包结构,与@Configuration一起使用,可代替 <context:component-scan base-package=“cn.cx”/>
@Import:引入新的配置类
@Bean:把该方法创建的对象存入到IoC容器中,当有一些开源对象需要使用注解时,如果采用纯注解开发,我们无法在其源码上加注解,就可以使用该标签。

Spring整合Junit单元测试的注解:

@RunWith
@ContextConfiguration,与@RunWith一起使用,可以代替加载配置文件的API使用。

什么是AOP(Aspect Oriented Programming):

意为面向切面编程,是一种编程规范,采取横向抽取机制,采取横向抽取机制,优化了传统纵向继承体系的重复代码,可以在不修改程序的前提下,进行增强,解耦。
用于处理系统中分布于各个模块的横切关注点,比如事务管理、权限控制、缓存控制、日志打印等等。

SpringAOP底层原理:

JDK动态代理:代理对象实现真实对象功能(还可增强功能)。生成代理对象必须实现被代理对象所实现的相同接口(基于接口),由java反射包下的Proxy类和InvocationHandler接口实现动态代理功能,Proxy提供了创建动态代理类和实例的静态方法,InvocationHandler处理代理实例上的方法调用并返回结果(通过invoke方法),其本质是通过反射实现的。

CGLIB代理:生成代理对象继承被代理对象(基于类)

AOP术语:

Joinpoint(连接点):被代理类中(实现类)的各个方法
Pointcut(切入点):程序增强的入口,需要编写表达式(Spring框架使用AspectJ切入点表达式语言),指示程序哪些方法进行增强(自己编写),可以将切入点理解为需要被拦截的连接点
Advice(通知/增强):切面类中的方法,代码的具体逻辑,有前置、后置、最终、异常、环绕几种(自己编写)
Target(目标对象): 被代理对象
Proxy(代理):代理对象(真正执行方法的)
Aspect(切面):切入点+增强构成切面,自定义的切面类(增强方法写在里面)要先加入IOC容器。
Weaving(织入):把增强逻辑应用到被代理对象来创建新的代理对象的过程。

AOP配置格式:
<?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"
       xmlns:aop="http://www.springframework.org/schema/aop"
       xmlns:tx="http://www.springframework.org/schema/tx"
       xsi:schemaLocation="
        http://www.springframework.org/schema/beans
        http://www.springframework.org/schema/beans/spring-beans.xsd
        http://www.springframework.org/schema/context
        http://www.springframework.org/schema/context/spring-context.xsd
        http://www.springframework.org/schema/aop
        http://www.springframework.org/schema/aop/spring-aop.xsd
        http://www.springframework.org/schema/tx
        http://www.springframework.org/schema/tx/spring-tx.xsd">

    <!--配置切面类,把该类交给IOC容器管理-->
    <bean id="myXmlAspect" class="cn.cx.aop.MyXmlAspect"/>

    <!--配置AOP的通知增强-->
    <aop:config>
        <!--使用切面类-->
        <aop:aspect ref="myXmlAspect">
        	<!--
                method()表示切面类中的方法(执行的增强方法)
                pointcut表示切入点:save()
            -->
            <aop:before method="log" pointcut="execution(public void cn.cx.aop.OrderServiceImpl.sava())"/>
        </aop:aspect>
    </aop:config>
</beans>

AOP通知类型:

前置通知aop:before:目标方法执行前进行增强
最终通知aop:after:目标方法执行成功或者失败进行增强
后置通知aop:after-returning:目标方法执行成功进行增强
异常通知aop:after-throwing:目标方法执行失败进行增强
环绕通知aop:around:目标方法执行前后都可以进行增强。目标对象方法需要手动执行

切入点表达式语法:

execution():固定写法。
public可以省略不写,返回值必须写,返回值可以用 * 通用的表示,重载方法都会被查找到。
包名+类名必须写,也可以用 * 通用表示,如cn.tx. * /cn.tx. * . * /cn.tx. * . * ServiceImpl。
方法名必须写,也可以使用*表示全部方法。
参数列表,(…)表示任意类型和个数的参数,可以想成可变参数。

AOP注解开发,要在配置文件中先加上:

<!--开启自动代理-->
<aop:aspectj-autoproxy/>
AOP常用注解:

@Aspect:声明当前类切面类,相当于<aop:aspect ref=“xxx”>
@Before:在切面类中增强方法上使用该注解,相当于<aop:before >,后置,最终效果和该标签同理。
@After: 后置通知:目标方法之后执行(始终执行)
@AfterReturning:返回之后通知:执行方法结束之前执行(异常不执行)
@Around:环绕通知:环绕目标方法执行
@AfterThrowing:异常通知:出异常后执行
@EnableAspectJAutoProxy:开启AOP自动代理

Spring加载属性文件:

<!--加载properties属性文件-->
<context:property-placeholder location="classpath:xxx.properties"/>

Spring声明式事务管理:

相关的类:
PlatformTransactionManager:平台事务管理器,不同的持久层框架,使用不同的实现类。

TransactionDefinition:事务定义信息类,传播行为(一个方法内调用另一方法,牵扯到两个事务)、超时、只读等等。

TransactionStatus:事务状态。

事务管理配置文件格式:

<?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"
       xmlns:aop="http://www.springframework.org/schema/aop"
       xmlns:tx="http://www.springframework.org/schema/tx"
       xsi:schemaLocation="
        http://www.springframework.org/schema/beans
        http://www.springframework.org/schema/beans/spring-beans.xsd
        http://www.springframework.org/schema/context
        http://www.springframework.org/schema/context/spring-context.xsd
                http://www.springframework.org/schema/aop
                http://www.springframework.org/schema/aop/spring-aop.xsd
                http://www.springframework.org/schema/tx
            http://www.springframework.org/schema/tx/spring-tx.xsd">

    <!--配置平台事务管理器-->
    <bean id="transactionManager" class="org.springframework.jdbc.datasource.DataSourceTransactionManager">
        <property name="dataSource" ref="dataSource" />
    </bean>

    <!--配置事务的通知(没有自己编写切面类,通知方法也不是自己编写,Spring框架提供的)-->
    <tx:advice id="txAdvice" transaction-manager="transactionManager">
        <tx:attributes>
            <!--对方法进行增强,设置隔离级别,传播行为,超时的时间-->
            <tx:method name="xxx" isolation="DEFAULT" propagation="REQUIRED" />
        </tx:attributes>
    </tx:advice>

    <!--配置AOP的增强-->
    <aop:config>
        <!--Spring框架提供系统通知,使用advisor标签-->
        <aop:advisor advice-ref="txAdvice" pointcut="execution(public * cn.cx.pay.AccountServiceImpl.pay(..))" />
    </aop:config>

</beans>

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值