Spring篇

1 IOC本质

控制反转loC(Inversion of Control),是一种设计思想,DI(依赖注入)是实现loC的一种方法。没有loC的程序中,我们使用面向对象编程,对象的创建与对象间的依赖关系完全硬编码在程序中,对象的创建由程序自己控制,控制反转后将对象的创建转移给第三方,所谓控制反转就是:获得依赖对象的方式反转了。

loC是Spring框架的核心内容,使用多种方式完美的实现了IoC,可以使用XML配置,也可以使用注解,新版本的Spring也可以零配置实现loC。

Spring容器在初始化时先读取配置文件,根据配置文件或元数据创建与组织对象存入容器中,程序使用时再从loc容器中取出需要的对象。

控制反转是一种通过描述(XML或注解)并通过第三方去生产或获取特定对象的方式。在Spring中实现控制反转的是loC容器,其实现方法是依赖注入(Dependency Injection,Dl)。

2 IOC创建对象的方式

package examples;

public class ExampleBean {

    // Number of years to calculate the Ultimate Answer
    private final int years;

    // The Answer to Life, the Universe, and Everything
    private final String ultimateAnswer;

    public ExampleBean(int years, String ultimateAnswer) {
        this.years = years;
        this.ultimateAnswer = ultimateAnswer;
    }
}

使用无参构造对象,默认

使用有参构造的三种方式

  1. 下标赋值
<bean id="exampleBean" class="examples.ExampleBean">
    <constructor-arg index="0" value="7500000"/>
    <constructor-arg index="1" value="42"/>
</bean>
  1. 类型赋值
<bean id="exampleBean" class="examples.ExampleBean">
    <constructor-arg type="int" value="7500000"/>
    <constructor-arg type="java.lang.String" value="42"/>
</bean>
  1. 参数名
<bean id="exampleBean" class="examples.ExampleBean">
    <constructor-arg name="years" value="7500000"/>
    <constructor-arg name="ultimateAnswer" value="42"/>
</bean>

总结:在配置交件加载的时候,容器中管理的对象就已经初始化了!|

3 Spring配置

3.1 别名

<!--别名,如果添加了别名,我们也可以使用别名获取到这个对象-->
<alias name="user" alias="userNew" />

3.2 Bean配置

id : bean的唯一标识符,也就是相当于我们学的对象名
class : bean对象所对应的全限定名:包名+类型name :也是别名,而且name可以同时取多个别名
-->
<bean id="userT" c1ass="com. kuang.pojo.userT" name="user2 u2,u3;u4">
<property name="name" value="张三"/>

3.3 import

这个import,一般用于团队开发使用,他可以将多个配置文件,导入合并为一个
假设,现在项目中有多个人开发,这三个人复制不同的类开发,不同的类需要注册在不同的bean中,我们可以用import将所有人的beans.xml合并为一个总的!

  • 张三
  • 李四
  • 王五
  • applicationContext.xml
<beans>
    <import resource="services.xml"/>
    <import resource="resources/messageSource.xml"/>
    <import resource="/resources/themeSource.xml"/>

    <bean id="bean1" class="..."/>
    <bean id="bean2" class="..."/>
</beans>

4 依赖注入

Dependency injection (DI) is a process whereby objects define their dependencies (that is, the other objects with which they work) only through constructor arguments, arguments to a factory method, or properties that are set on the object instance after it is constructed or returned from a factory method. The container then injects those dependencies when it creates the bean. This process is fundamentally the inverse (hence the name, Inversion of Control) of the bean itself controlling the instantiation or location of its dependencies on its own by using direct construction of classes or the Service Locator pattern.

译文:

依赖注入(DI)是一个过程对象定义它们的依赖项(也就是说,他们工作的其他对象)只能通过构造函数参数,参数工厂方法或对象实例上设置的属性构造或从工厂回来后的方法。然后容器注入这些依赖项时创建bean。这个过程从根本上是反(因此得名,控制反转)bean本身的控制实例化或位置的依赖自己的使用直接建设类或服务定位器模式。

4.1 构造器注入

前面第二点已经所过,就是使用构造器创建对象

4.2 Set方式注入(√)

1.普通值注入

<bean id="myDataSource" class="org.apache.commons.dbcp.BasicDataSource" destroy-method="close">
    <!-- results in a setDriverClassName(String) call -->
    <property name="driverClassName" value="com.mysql.jdbc.Driver"/>
    <property name="url" value="jdbc:mysql://localhost:3306/mydb"/>
    <property name="username" value="root"/>
    <property name="password" value="misterkaoli"/>
</bean>

2.Bean注入,ref

<bean id="accountService"  class="全限定类名">
    <property name="target" ref="otherBeanId">
    </property>
</bean>

3 数组

<bean id="accountService"  class="全限定类名">
    <property name="target">
    	<array>
    		<value>值1</value>
    		<value>值2</value>
    		<value>值3</value>
    	</array>
    </property>
</bean>

4 Collections

<bean id="moreComplexObject" class="example.ComplexObject">
    <!-- results in a setAdminEmails(java.util.Properties) call -->
    <property name="adminEmails">
        <props>
            <prop key="administrator">administrator@example.org</prop>
            <prop key="support">support@example.org</prop>
            <prop key="development">development@example.org</prop>
        </props>
    </property>
    <!-- results in a setSomeList(java.util.List) call -->
    <property name="someList">
        <list>
            <value>a list element followed by a reference</value>
            <ref bean="myDataSource" />
        </list>
    </property>
    <!-- results in a setSomeMap(java.util.Map) call -->
    <property name="someMap">
        <map>
            <entry key="an entry" value="just some string"/>
            <entry key ="a ref" value-ref="myDataSource"/>
        </map>
    </property>
    <!-- results in a setSomeSet(java.util.Set) call -->
    <property name="someSet">
        <set>
            <value>just some string</value>
            <ref bean="myDataSource" />
        </set>
    </property>
</bean>

5 空值

<bean class="ExampleBean">
    <property name="email" value=""/>
</bean>
<bean class="ExampleBean">
    <property name="email">
        <null/>
    </property>
</bean>

4.3 拓展方式注入

1 p命名空间注入

需要依赖第三方的约束

<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"
    xsi:schemaLocation="http://www.springframework.org/schema/beans
        https://www.springframework.org/schema/beans/spring-beans.xsd">

    <bean name="classic" class="com.example.ExampleBean">
        <property name="email" value="someone@somewhere.com"/>
    </bean>
    
	<!--p命名空间注入,可以注入属性的值-->
    <bean name="p-namespace" class="com.example.ExampleBean"
        p:email="someone@somewhere.com"/>
</beans>

2 c命名空间注入

通过构造方式注入

<beans xmlns="http://www.springframework.org/schema/beans"
    xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
    xmlns:c="http://www.springframework.org/schema/c"
    xsi:schemaLocation="http://www.springframework.org/schema/beans
        https://www.springframework.org/schema/beans/spring-beans.xsd">

    <bean id="beanTwo" class="x.y.ThingTwo"/>
    <bean id="beanThree" class="x.y.ThingThree"/>

    <!-- traditional declaration with optional argument names -->
    <bean id="beanOne" class="x.y.ThingOne">
        <constructor-arg name="thingTwo" ref="beanTwo"/>
        <constructor-arg name="thingThree" ref="beanThree"/>
        <constructor-arg name="email" value="something@somewhere.com"/>
    </bean>

    <!-- c-namespace declaration with argument names -->
    <bean id="beanOne" class="x.y.ThingOne" c:thingTwo-ref="beanTwo"
        c:thingThree-ref="beanThree" c:email="something@somewhere.com"/>

</beans>

注意点:p命名和c命名空间不能直接使用,需要导入xml约束

xmlns:p="http://www.springframework.org/schema/p
xmlns:c="http://www.springframework.org/schema/c

4.4 Bean的作用域

ScopeDescription
singleton(Default) Scopes a single bean definition to a single object instance for each Spring IoC container.
prototypeScopes a single bean definition to any number of object instances.
requestScopes a single bean definition to the lifecycle of a single HTTP request. That is, each HTTP request has its own instance of a bean created off the back of a single bean definition. Only valid in the context of a web-aware Spring ApplicationContext.
sessionScopes a single bean definition to the lifecycle of an HTTP Session. Only valid in the context of a web-aware Spring ApplicationContext.
applicationScopes a single bean definition to the lifecycle of a ServletContext. Only valid in the context of a web-aware Spring ApplicationContext.
websocketScopes a single bean definition to the lifecycle of a WebSocket. Only valid in the context of a web-aware Spring ApplicationContext.

1.单例模式
(默认)所有bean共享一个对象

<bean id="accountService" class="com.something.DefaultAccountService" scope="singleton"/>

2.原型模式
每次从容器中get的时候,都会产生一个新对象!(一般多线程时使用)

<bean id="accountService" class="com.something.DefaultAccountService" scope="prototype"/>

3.其余的request、session、application、这些个只能在web开发中使用到!

5 Bean的自动装配

  • 自动装配是Spring满足bean依赖一种方式!
  • Spring会在上下文中自动寻找,并自动给bean装配属性!

在Spring中有三种装配的方式
1.在xml中显示的配置
2.在java中显示配置
3.隐式的自动装配bean【重要】

5.1 ByName 自动装配

    <bean name="classic" class="com.example.ExampleBean" autowire="byName">
        <property name="email" value="someone@somewhere.com"/>
    </bean>

5.2 ByType自动装配

    <bean name="classic" class="com.example.ExampleBean" autowire="byType">
        <property name="email" value="someone@somewhere.com"/>
    </bean>

小结:

  • byname的时候,需要保证所有bean的id唯一,并且这个bean需要和自动注入的属性的set方法的值一致!
  • bytype的时候,需要保证所有bean的class唯一,并且这个bean需要和自动注入的属性的set方法的值一致!

5.3 使用注解自动装配

JDK1.5支持的注解,Spring2.5就开始支持注解

使用注解的须知:
1.导入约束:context约束
2.配置注解的支持: context:annotation-config/

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

</beans>

@Autowired

  • 直接在属性上使用即可!也可以在set方式上使用!
  • 使用Autowired我们可以不用编写Set方法了,前提是你这个自动装配的属性在IOC (Spring)容器中存在,且符合名字byname!

如果@Autowired自动装配的环境比较复杂,自动装配无法通过一个注解【@Autowired】完成的时候、我们可以使用@Qualifier(value=“xxx”)去配置@Autowired的使用,指定一个唯一的bean对象注入!

@ resource name属性。默认情况下,Spring解释价值作为bean名称被注入。换句话说,它是通过名称的语义,证明在以下例子:

public class SimpleMovieLister {

    private MovieFinder movieFinder;

    @Resource(name="myMovieFinder") 
    public void setMovieFinder(MovieFinder movieFinder) {
        this.movieFinder = movieFinder;
    }
}

小结:
@Resource和@ Autowired的区别:

  • 都是用来自动装配的,都可以放在属性字段上
  • @Autowired 通过byType的方式实现,而且必须要求这个对象存在!【常用】
  • @Resource默认通过byname的方式实现,如果找不到名字,则通过byType实现!如果两个都找不到的情况下,就报错!【常用】
  • 执行顺序不同:@ Autowired 通过byType的方式实现。

6 使用注解开发

在spring4.5之后要使用注解必须要保证导入了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"
    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:component-scan base-package="com.xxx.xxx">
    <context:annotation-config/>

</beans>

1.bean
使用@Component注解类

2.属性注入

@Component
public class User{
	public String name;

	//相当于<property name="name" value="张三">
	@Value("张三")
	public void setName(String name){
		this.name = name;
	}
}

3.衍生的注解
@Component 有几个衍生注解,我们在web开发中,会按照mvc三层架构分层!

  • dao【Repository】
  • service【Service】
  • controller【Controller】

这四个注解功能都是一样的,都是代表将某个类注册到Spring中,装配bean

4.自动装配置

@Autowired :自动装配通过类型。名字
      如果Autowired不能唯一自动装配上属性,则需要通过
@Qualifier(value=“xxx”)@Nu77able字段标记了这个注解,说明这个字段可以为nu17;
@Resource:自动装配通过名字。类型。

5.作用域
注解类,后面跟作用域

@Component
@Scope("prototype")
public class User{
//.........
}

6.小结
xml与注解:

  • xml 更加万能,适用于任何场合!维护简单方便。
  • 注解不是自己类使用不了,维护相对复杂!

xml与注解最佳实践:

  • xml 用来管理bean;
  • 注解只负责完成属性的注入;
  • 我们在使用的过程中,只需要注意一个问题:必须让注解生效,就需要开启注解的支持

7 使用java方式配置Spring

官方文档1.12 传送门

8 AOP

官方文档第5点 传送门

8.1 什么是AOP?

面向方面编程 (AOP) 通过提供另一种思考程序结构的方式来补充面向对象编程 (OOP)。OOP 中模块化的关键单位是类,而 AOP 中模块化的单位是aspect。aspect能够实现跨越多种类型和对象的切入点(例如事务管理)的模块化。

8.2 AOP在Spring中的作用

提供声明式事务;允许用户自定义切面

  • 横切关注点:跨越应用程序多个模块的方法或功能。即是,与我们业务逻辑无关的,但是我们需要关注的部分,就是横切关注点。如日志,安全,缓存,事务等等…
  • 切面(ASPECT):横切关注点被模块化的特殊对象。即,它是一个类。
  • 通知(Advice) :切面必须要完成的工作。即,它是类中的一个方法。
  • 目标(Target)︰被通知对象。
  • 代理(Proxy):向目标对象应用通知之后创建的对象。
  • 切入点(PointCut):切面通知执行的“地点"的定义。
  • 连接点(JointPoint) :与切入点匹配的执行点。

SpringAOP中,通过Advice定义横切逻辑,Spring中支持5种类型的Advice:

通知类型连接点实现接口
前置通知方法方法前org.springframework.aop.MethodBeforeAdvice
后置通知方法后org.springframework.aop.AfterReturningAdvice
环绕通知方法前后org.aopalliance.intercept.MethodInterceptor
异常抛出通知方法抛出异常org.springframework.aop.ThrowsAdvice
引介通知类中增加新的方法属性org.springframework.aop.IntroductionInterceptor

即Aop在不改变原有代码的情况下,去增加新的功能.

8.3 使用Spring实现AOP

【重点】使用AOP织入,需要导入一个依赖包!

<!-- https : / /mvnrepository.com/artifact/org.aspectj/aspectjweaver -->
<dependency>
	<groupId>org.aspectj</groupId>
	<artifactId>aspectjweaver</artifactId>
	<version>1.9.4</version>
</dependency>
<?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/aop"
    xsi:schemaLocation="http://www.springframework.org/schema/beans
        https://www.springframework.org/schema/beans/spring-beans.xsd
        http://www.springframework.org/schema/aop
        https://www.springframework.org/schema/aop/spring-aop.xsd">

</beans>

方式一:使用Spring的API接口【主要是Spring接口实现】
没有配置切面

<!--这个bean的类xxx实现了SpringAPI-->
<bean id="mybean" class="xxxx.xxxx.xxx">

<aop:config>
        <aop:pointcut id="businessService"
            expression="execution(* com.xyz.myapp.service.*.*(..)) and this(service)"/>
        <aop:before pointcut-ref="businessService" before-ref="mybean"/>
        ...
</aop:config>

方式二:自定义来实现AOP【主要是定义切面】

<aop:config>

    <aop:aspect id="myAspect" ref="aBean">
        <aop:pointcut id="businessService"
            expression="execution(* com.xyz.myapp.service.*.*(..)) and this(service)"/>
        <aop:before pointcut-ref="businessService" method="monitor"/>
        ...
    </aop:aspect>
</aop:config>

方式三:注解方式实现AOP

使用注解要开启注解支持

<aop:aspectj-autoproxy>
import org.aspectj.lang.annotation.Aspect;
import org.aspectj.lang.annotation.Before;

@Aspect
public class BeforeExample {

    @Before("com.xyz.myapp.CommonPointcuts.dataAccessOperation()")
    public void doAccessCheck() {
        // ...
    }

//@AfterReturning("com.xyz.myapp.CommonPointcuts.dataAccessOperation()")
//  @AfterThrowing("com.xyz.myapp.CommonPointcuts.dataAccessOperation()")
// @After("com.xyz.myapp.CommonPointcuts.dataAccessOperation()")
//@Around("com.xyz.myapp.CommonPointcuts.businessService()")
}

顺序:环绕前(Around),方法执行前(Before),环绕后(Around),返回值后(AfterReturning),方法执行后(After)

9 事务式声明

整合和事务处理官方文档
http://mybatis.org/spring/index.html

9.1 事务

  • 把一组业务当成一个业务来做;要么都成功,要么都失败!
  • 事务在项目开发中,十分的重要,涉及到数据的一致性问题,不能马虎!
  • 确保完整性和一致性;

事务的ACID原则:

  • 原子性
  • 一致性
  • 隔离性(多个业务可能同操作一个资源,防止数据损坏)
  • 持久性(事务一旦提交,无论系统发生什么问题,结果都不会再被影响,被持久化的写到存储器中!)

9.2 Spring中的事务管理

  • 声明式事务:AOP
  • 编程式事务
<!--sqlSessionTempLate:就是我们使用的sqlsession-->
<bean id="sq1Session" class="org.mybatis.spring.sq1sessionTemplate">
	<!--只能使用构造器注入sqlSessionFactory,因为它没有set方法-->
	<constructor-arg index="e" ref="sqlsessionFactory" />
</bean>
<!--配置声明式事务-->
bean id="transactionManager" class="org.springframework. jdbc.datasource.DataSourceTransactionManag
	<property name="datasource" ref="dataSource"/>
</ bean>

<!--结合A0P实现事务的织入-->
<!--配置事务通知;-->
<tx:advice id="txAdvice" transaction-manager="transactionManager">
	<!--给那些方法配置事务-->
	<!--配置事务的传播特性: newpropagation= -->
	<tx:attributes>
		<tx:method name="add" propagation="REQUIRED"/>
		<tx:method name="delete" propagation="REQUIRED"/>
		<tx :method name="update" propagation="REQUIRED"/>
		<tx:method name="query" read-only="true"/>
		<tx:method name="*" propagation="REQUIRED"/>
	</tx:attributes>
</tx:advice>

<! --配置事务切入-->
<aop:config>
	<aop:pointcut id="txPointCut"expression="execution(*com.kuang.mapper.*.*(..))"/>
	<aop:advisor advice-ref="txAdvice" pointcut-ref="txPointCut"/>
< /aop: config>

数据治理是确保数据准确性、可靠性、安全性、可用性和完整性的体系和框架。它定义了组织内部如何使用、存储、保护和共享数据的规则和流程。数据治理的重要性随着数字化转型的加速而日益凸显,它能够提高决策效率、增强业务竞争力、降低风险,并促进业务创新。有效的数据治理体系可以确保数据在采集、存储、处理、共享和保护等环节的合规性和有效性。 数据质量管理是数据治理中的关键环节,它涉及数据质量评估、数据清洗、标准化和监控。高质量的数据能够提升业务决策的准确性,优化业务流程,并挖掘潜在的商业价值。随着大数据和人工智能技术的发展,数据质量管理在确保数据准确性和可靠性方面的作用愈发重要。企业需要建立完善的数据质量管理和校验机制,并通过数据清洗和标准化提高数据质量。 数据安全与隐私保护是数据治理中的另一个重要领域。随着数据量的快速增长和互联网技术的迅速发展,数据安全与隐私保护面临前所未有的挑战。企业需要加强数据安全与隐私保护的法律法规和技术手段,采用数据加密、脱敏和备份恢复等技术手段,以及加强培训和教育,提高安全意识和技能水平。 数据流程管理与监控是确保数据质量、提高数据利用率、保护数据安全的重要环节。有效的数据流程管理可以确保数据流程的合规性和高效性,而实时监控则有助于及时发现并解决潜在问题。企业需要设计合理的数据流程架构,制定详细的数据管理流程规范,并运用数据审计和可视化技术手段进行监控。 数据资产管理是将数据视为组织的重要资产,通过有效的管理和利用,为组织带来经济价值。数据资产管理涵盖数据的整个生命周期,包括数据的创建、存储、处理、共享、使用和保护。它面临的挑战包括数据量的快速增长、数据类型的多样化和数据更新的迅速性。组织需要建立完善的数据管理体系,提高数据处理和分析能力,以应对这些挑战。同时,数据资产的分类与评估、共享与使用规范也是数据资产管理的重要组成部分,需要制定合理的标准和规范,确保数据共享的安全性和隐私保护,以及建立合理的利益分配和权益保障机制。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值