IT数码 购物 网址 头条 软件 日历 阅读 图书馆
TxT小说阅读器
↓语音阅读,小说下载,古典文学↓
图片批量下载器
↓批量下载图片,美女图库↓
图片自动播放器
↓图片自动播放器↓
一键清除垃圾
↓轻轻一点,清除系统垃圾↓
开发: C++知识库 Java知识库 JavaScript Python PHP知识库 人工智能 区块链 大数据 移动开发 嵌入式 开发工具 数据结构与算法 开发测试 游戏开发 网络协议 系统运维
教程: HTML教程 CSS教程 JavaScript教程 Go语言教程 JQuery教程 VUE教程 VUE3教程 Bootstrap教程 SQL数据库教程 C语言教程 C++教程 Java教程 Python教程 Python3教程 C#教程
数码: 电脑 笔记本 显卡 显示器 固态硬盘 硬盘 耳机 手机 iphone vivo oppo 小米 华为 单反 装机 图拉丁
 
   -> Java知识库 -> Spring -> 正文阅读

[Java知识库]Spring

Spring

1、Spring

1.1、简介

spring:春天–>给软件行业带来了春天!

2002年首次推出Spring框架的雏形:interFace21框架

Spring理念:使现有技术更加容易使用,本身是一个大杂烩,整合了现有的技术框架!

官网:http://spring.io/projects/spring-framework#overview

官方下载地址:http://repo.spring.io/release/org/springframework/spring

GitHub:https://github.com/spring-projects/spring-framework

maven:springWebMvc

 <!--https://mvnrepository.com/artifact/org.springframework/spring-webmvc -->
 <dependency>
	<groupId>org. springframework</groupId>
	<artifactId> spring-webmvc </artifactId>
	<version>5.2.0. RELEASE</version>
</ dependency>
 <!-- https://mvnrepository.com/artifact/org.springframework/spring-webmvc -->
<dependency>
	<groupId>org. springframework</groupId>
	<artifactId>spring-jdbc</artifactId>
	<version>5.2.0. RELEASE</version>
</ dependency>

1.2、优点

spring是一个开源的免费的框架(容器)!

spring是一个轻量级的、非入侵式的框架!

核心:控制反转(IOC),面向切面编程(AOP)。

支持事务的处理,对框架整合的支持!

总结:Spring就是一个轻量级的控制反转(IOC)和面向切面编程(AOP)的框架!

1.3、组成

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-tn2fLcVr-1665910219491)(C:\Users\Administrator\AppData\Roaming\Typora\typora-user-images\image-20221015120123109.png)]

1.4、扩展

在Spring的官网有这个介绍:现代化的Java开发!说白了就是基于Spring的开发!

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-SXrna4Cd-1665910219493)(C:\Users\Administrator\AppData\Roaming\Typora\typora-user-images\image-20221015120254101.png)]

SpringBoot

一个快速开发的脚手架。

基于Spring Boot可以快速的开发单个微服务。

约定大于配置!

Spring Cloud

Spring Cloud是基于Spring Boot实现的。

Spring弊端:发展太久之后,违背了原来的理念,配置十分繁琐,人称“配置地狱”!

2、IOC理论推导

1、userDao接口

2、UserDaoImpl实现类

3、UserService业务接口

4、UserServiceImpl业务实现类

(建立多模块项目:先新建一个项目,将src文件夹删除,然后在项目上右键,新建一个项目)

在我们之前的业务中,用户的需求可能会影响我们原来的代码,我们需要根据用户的需求去修改原代码!

代码量十分大,修改一次的成本代价十分昂贵!

我们使用一个set接口实现,已经发现了革命性的变化!

private userDao userDao;
//利用set进行动态实现值的注入!
pub1ic void setuserDao(userDao userDao) {
this. userDao = userDao;
}

●之前,程序是主动创建对象!控制权在程序猿手上!

●使用了set注入后,程序不再具有主动性,而是变成了被动的接受对象!

这种思想,从本质上解决了问题,我们程序猿不用再去管理对象的创建了。系统的耦合性大大降低了,可以更加专注的在业务的实现上!这是IOC的原型!

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-xG0eembB-1665910219494)(C:\Users\Administrator\AppData\Roaming\Typora\typora-user-images\image-20221015122223201.png)]

3、ioc本质

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

loC是Spring框架的核心内容,使用多种方式完美的实现了IoG,可以使用XML配置,也可以使用注解,新版本的Spring也可以零配置实现IoC。
Spring容器在初始化时先读取配置文件,根据配置文件或元数据创建与组织对象存入容器中,程序使用时再从Ioc容器中取出需要的对象。

采用XML方式配置Bean的时候,Bean的定 义信息是和实现分离的,而采用注解的方式可以把两者合为一体,Bean的定义信息直接以注解的形式定义在实现类中,从而达到了零配置的目的。控制反转是一种通过描述(XML或注解)井通过第三方去生产或获取特定对象的方式。在Spring中实现控制反转的是IoC容器,其实现方法是依赖注入(Dependency Injection,DI)。

4、Spring的Hello项目

1、新建一个项目,导入依赖

<!-- https://mvnrepository.com/artifact/org.springframework/spring-web -->
    <dependency>
      <groupId>org.springframework</groupId>
      <artifactId>spring-web</artifactId>
      <version>5.3.23</version>
</dependency>
<dependency>
            <groupId>org.springframework</groupId>
            <artifactId>spring-context</artifactId>
            <version>5.3.22</version>
            <scope>test</scope>
</dependency>

2、新建一个Hello对象

package com.java.pojo;

public class Hello {
    private String str;

    public String getStr() {
        return str;
    }

    public void setStr(String str) {
        this.str = str;
    }

    @Override
    public String toString() {
        return "Hello{" +
                "str='" + str + '\'' +
                '}';
    }
}

3、书写Spring配置applicationContext.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">

<!--使Spring来创建对象,d在Spring 这些都欣sBean-->
<bean id="hello" class="com.java.pojo.Hello">
   <!-- 相当于给对象中的属性设置一个值-->
    <property name="str" value= "Spring"/>
</bean>
</beans>

4、书写测试类

import com.java.pojo.Hello;
import org.springframework.context.ApplicationContext;
import org.springframework.context.support.ClassPathXmlApplicationContext;

public class MySpring {
    public static void main(String[] args) {
        //获取spring的上下文对象1
        ApplicationContext context = new ClassPathXmlApplicationContext("beans.xm1");
        //我们的对象理在都在Spring中的管理了,我们要使心。直接去望面收出来就可以!
        Hello he11o = (Hello) context .getBean("hello");
        System.out.println(he11o.toString());

    }
}

输出结果

Hello{str='Spring'}

Hello 对象是谁创建的?
hello对象是由Spring创建的。
Hello对象的属性是怎么设置的?
hello对象的属性是由Spring容器设置的。

这个过程就叫控制反转:
控制:谁来控制对象的创建,传统应用程序的对象是由程序本身控制创建的,使用Spring后,对象是由Spring来创建的.
反转:程序本身不创建对象,而变成被动的接收对象.
依赖注入:就是利用set方法来进行注入的.
IOC是一种编程思想,由主动的编程变成被动的接收.
可以通过newClassPathXmlApplicationContext去浏览一下底层源码 .

OK,到了现在,我们彻底不用再程序中去改动了,要实现不同的操作,只需要在xml配置文件中进行修改,所谓的IoC,-句话搞定:对象由Spring来创建,管理,装配!

直接使用业务层

<bean id="mysqlImp1" class="com. kuang . dao. UserDaoMysq1Imp1"/>
<bean id= "orac1eImpl" class=" com. kuang. dao. UserDaoorac1eImpl-/>
<bean id= "JserServiceImp1" class=" com. kuang. service .UserServiceImpl">
<!--ref :引Spring 容器中创建好的对象-->
<property name="userDao" ref= "mysq1Imp1"/>
</bean>

测试:

public static void main(string[] args) {
//获4收Appl icationContext;秀 pring的容器
ApplicationContext context = new ClassPathXmlApplicationContext( configLocation; "beans . xm1");
//容器在手。天卜我有。需要什么。就直孩get什么!
UserServiceImpl userServiceImpl =(UserServiceImp1)context.getBean(s:"UserServiceImp1");
userServiceImpl . getUser();
}

5、IOC创建对象的方式

1、使用无参构造方法创建对象,默认!

2.假设我们要使用有参构造创建对象。
1.下标赋值

<!--&lt; !&ndash;第一种, 下标献值: &ndash;&gt;-->
<bean id= "user" class= "com. kuang. pojo. User">
<constructor-arg index="e" value=" 测试下标赋值"/>
</bean>

2.通过类型创建

不建议使用
<bean id="user" class=" com. kuang . pojo .User">
<constructor-arg type=" java。lang . String" value="ceshi" />
</bean>

3.直接通过参数名

<bean id="user" classm" com. kuang. pojo.User">
<constructor- arg nhame="name" value=" ceshi"/>
< /bean>

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

6、spring配置

6.1、别名

一对一

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

6.2、bean配置

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

6.3、import

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

●李四
●王五

<import resource="beans .xml"/>
<import resource="beans2 .xml"/>
< import resource="beans3 . xml" />

使用的时候,直接使用总的配置就可以了

7、依赖注入

7.1、构造器注入

前面已经说过了

7.2、set方式注入(重点)

依赖注入:set注入!

依赖:bean对象的创建依赖于容器!

注入:bean对象中的所有属性,由容器来注入!

<bean id=" address" class="com. kuang . pojo . Address"/>
<bean id="student" class="com. kuang. pojo. Student">
<!-第一种,普通值注入。value-->
<property name="name" value="哇哇哇哇哇"/>
<!--第二种。Bean注入。 ref-->
<property name=" address" ref= " address" />
<!--数组注入,ref-->
<property name= "books">
<array>
<value>红楼梦</va1ue>
<value>西游记</value>
<value>水浒传</value>
<value>三国演义</value>
</array>
</property>
</bean>
<!--List-->
<property name= "hobbys">
<list>
<value>听歌</value>
<value>船代码< /value>
<value>看电影</value>
</list>
</ property>
<!--Map-->
<property name= ”card">
<map>
<entry key= "" value=""/>
<entry key="" value=""/>
<entry key="" value=""/>
</map>
</ property>
<!--Set-->
<property name=' games " >
<set>
<value>L0L</va1ue>
<value>COC< /value>
<value> BOB< /value>
</set>
</ property>
<!--null-->
(property name-"wife">
<nu1l/>
</property>
<!--Properties-->
<property name=" info">
<props>
<prop key= ”driver" >28198525</prop>
<prop key= "url"></prop>
<prop key= "username”>root</prop>
<prop key="password" >123456/prop>
</props>
</property>

7.3、扩展方式注入

p命令和c命令

首先导入命名空间(P命令)

xmIns:p-="http://www.springframework.org/schema/p

使用:

<!--p命名空间注入。可以直接注入属性的值: property-->
<bean id="user" class="com. kuang. pojo.User" p:name=" 啊啊啊啊啊啊" p:age="18"/>

(c命令)要先加无参构造

xmLnsic= http://www.springframework.org/scnema/c"

使用:

<1--c命名空问注入。遇过构选器注入: construct-args-->
<bean id="user2" class=" com. kuang. pojo.user" c:age= "18" c:name="aaaaa"/>

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

7.4、bean的作用域

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-MbQLZIFd-1665910219495)(C:\Users\Administrator\AppData\Roaming\Typora\typora-user-images\image-20221015142608504.png)]

1、单例模式(Spring的默认机制)

<bean id="user" claas="con.fan.pojo.user"c:age="18" c:name="aaa" scope="singleton"/>

2、原型模式:每次从容器中get的时候,都会产生一个新对象!

<bean id="user" claas="con.fan.pojo.user"c:age="18" c:name="aaa" scope="prototype"/>

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

8、bean自动装配

自动装配是spring满足bean依赖的一种方式!

spring会在上下文中自动寻找,并自动给bean装配属性!

在spring中有三种装配方式

1.在xml中显示的配置

2.在Java中显示配置

3.隐式的自动装配bean(重要)

8.1、测试

1、环境搭建

? 一个人有两个宠物(猫狗)

8.2、autowire自动装配

<bean id="cat" class="com. kuang. pojo.cat"/>
<bean id="dog222” class=" com. kuang. pojo.Dog"/>
<!--
byName:会自动在容器上下文中查找。利自己对象set方法后面的值对应的beanid!
byType:会自动在容器上文中查找, 利自己对象属性类重相间的bean !
-->
<bean id="people" class=" com. kuang. pojo.People" autowire= "byName">
<property name=" name" value=" aaaa"/>
</bean>

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

bytype的时候,需要保证所有bean的lass唯一, 并且这个bean需要和自动注入的属性的类型一致!

8.3、使用注解实现自动装配

jdk1 .5支持的注解,Spring2.5就支持注解了 !

The introduction of annotation-based configuration raised the question of whether this approach is "better"than XML.

要使用注解须知:

1.导入约束: context约束

2.配置注解的支持: contextannotation-config/

<?xm1 version="1. 0" encoding="UTF-8"?>
<beans xmIns="http ://www. springframework. org/schema/beans"
xm1ns :xsi="http://www. w3. org/2001/xMLschema-instance"
xm1ns :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. springf ramework . org/ schema/context
https :/ /www. springframework. org/schema/context/spring-context. xsd">

    <context : annotation-config/>
</beans>

@AutoWired

直接在属性上使用即可!也可以用在set方法上。

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

科普:

@Nullable    字段标记了这个注解,说明这个字段可以为nu11:
 //如果显示定义TAutowired 的required属性为false, 说明这个对象可以为null, 否则不允许为空
@Autowired (required = false)
private Cat cat;

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

@Resource注解

public class People {
cResource (name = l"cat2")
private Cat cat;
Resource
private Dog dog;

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

●都是用来自动装配的,都可以放在属性字段上

●@ Autowired通过byname的方式实现,而且必须要求这个对象存在!(常用)

●@Resource默认通过byname的方式实现,如果找不到名字,则通过byType实现!如果两个都找不到的情况下,就报错!(常用)

●执行顺序不同: @ Autowired通过byType的方式实现

9、使用注解开发

在Spring4之后,要使用注解开发,必须要保证aop的包导入了

使用注解需要导入context约束,增加注解的支持!

<!--指定要扫描的包,这个包卜的注解就会生效-->
<context : component-scan base-package="com.fan.pojo"/>
<context : annotation-config/>

1、bean

//等价于 <bean id= "user" class= "com. fan. pojo. User"/>
//Component 组件
@Component
public class User {
public String name = "啊啊啊";
}

2.属性如何注入

@Component
public class user{
public string name;
//相当于cproperty name="name" value="aaa"/>
@value ("aaaa")
pub1ic void setName (string name) {
this.name = name ;
}
}

3、衍生的注解

@Compdnent有几个衍生注解,我们在web开发中,会按照mvc三层架构分层!
dao [@Repository]
service [@Service]
controller[@controller]

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

4、自动装配

- @Autowired :自动装配通过类型。名字
如果Autowi red不能唯一。 自动装配上属性,则需要通过@Qualifier(value="xxx")
- @Nu11able
字段标记了这个注解,说明这个字段可以为nu11;
- QResource
:自动装配通过名字。类型。

5、作用域

@component
@scope("prototype")//singlaton
public class user {
pub1ic string name;
//相当于sproperty name="name" value="kuangshen"/>
@value ("kuangshen2")
pub1ic void setName (string name) {
this.name = name ;
}
}

6、小结

xml与注解:
。xml更加万能,适用于任何场合!维护简单方便

。注解不是自己类使用不了

xml与注解最佳实践:
。xml用来管理bean;
。注解只负责完成属性的注入;

。我们在使用的过程中,只需要注意-个问题: 必须让注解生效,就需要开启注解的支持

<!--指定要扫描的包,这个包下的江解就会生效-->
<context :component-scan base-package="com.fan"/>
<context :annotation-config/>

10、使用Java的方式配置Spring

我们现在要完全不使用Spring的xml配置了,全权交给Java来做!|

JavaConfig是Spring的一个子项目,在Spring4之后, 它成为了一个核心功能!

//这里这个注解的点思,就是说名这个光被Spring按停了,注测到了容器中
@Component
public class User {
private String name;
public String getName() {
return name;
@Value("Fan" )
public void setName(String name) {
this.name = name;
}
@override
public string tostring() {
return "User{" +
"name=
+name+'\'+
'}";|
}
@Configuration//这个也会被spring容器托管,注册道容器中,因为它本来就是一个@component,@Configuration代表这是一个配置类, 就和我们之前看的beans . xmL
@ComponentScan(" com. fan . pojo" )
@Import ( FanConfig2.class)
public class FanConfig {
//注册一-个bean ,就相当于我们之 前号的一- 个bean标签
//这个方法的名字。就相当/bean标签中的id属性
//这个方法的函回值。就相当/bean标签中的class屙性
    @Bean
public User getUser(){
return new User();//.就是返阿要注入bean的对象!

}

测试:

public class MyTest {
public static void main(String[] args) {
    //如果完全使用 了配置类方式去做,我们就只能通过AnnotationConfig 上下文 來获取容器,通过配置类的class对象加载!
ApplicationContext context = new AnnotationConfigApplicationContext(FanConfig.class);
User getUser = (User) context .getBean( s: "getUser");
System. out . print1n(getUser . getName(0);
}

这种纯Java的配置方式,在SpringBoot中随处可见!

11、静态代理

11.1、AOP

1、代理模式

为什么要学习代理模式?因为着及时SpringAOP的底层【SpringAOP和SpringMVC】

代理模式的分类:

静态代理:

动态代理:

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-l9Yr4A2W-1665910219496)(C:\Users\Administrator\AppData\Roaming\Typora\typora-user-images\image-20221016144406775.png)]

11.2、静态代理

角色分析:

抽象角色:一般会使用接口或者抽象类来解决

真实角色:被代理的角色

代理角色:代理真实的角色后,我们一般会做一些附属操作

客户:访问代理对象的人!

代理模式的好处: .
●可以使真实角色的操作更加纯粹!不用去关注一些公共的业务
●公共也就就交给代理角色!实现了业务的分工!
●公共业务发生扩展的时候,方便集中管理!

代码步骤:
1.接口

//租房
public interface Rent {
public void rent();

2.真实角色

//房东
pub1ic class Host implements Rent {
public void rentO {
system. out.print1n("房东要出租房子! ");
}

3.代理角色

publ1c class Proxy implements Rent {
prlvate Host host;
public Proxy() {
public Proxy(Host host) {
this. host = host;
}
public void rent() {
seeHouse();
host. rent():
hetong();
fare();
}
//看房
public vold seeHouse(){
System . out . printIn("中介带你看房");
}
//租赁
public void hetong(){
System. out . printin("签租赁合同");
}
//收中介费
public void fare(){
System . out . println("收中介费" );
}
}

4.客户端访问代理角色

public class client {
public static void main(string[] args) {
//房东要租房子
Host host = new Host(;
//代理,中介帮房东租房子,但是呢?代理角一般会有一 些附属操作!
Proxy proxy = new Proxy(hoit);
//你不用面对房东。直按找中介租房即可!
proxy. rent();
}
}

缺点:
●一个真实角色就会产生-个代理角色;代码量会翻倍-开发效率会变低~

11.3、加深理解

用户userviceImpl有增删改查功能,现在需要加日志功能,在不改变原有代码的基础上,增加日志功能,这就是AOP思想,实现方式如下:

新建一个代理类,实现service的方法,在主体中引入userviceImpl对象,并写一个set方法,在该类中书写一个日志方法,增删改查方法重写时调用原有userviceImpl的增删改查方法,再在实现之前加入自己的日志方法即可。

11.4、动态代理

底层原理是反射
●动态代理和静态代理角色一样
●动态代理的代理类是动态生成的,不是我们直接写好的.

●动态代理分为两大类:基于 接口的动态代理,基于类的动态代理

。基于接口:JDK动态代理
。基于类: cglib
。java字节码实现: javasist

需要了解两个类: Proxy. InvocationHandler

InvocationHandler:调用处理程序
//等我们会用这个类,自动生成代理类!
public class ProxyInvocationHandler implements InvocationHandler {
1/被化理的接口
private Rent rent;
public void setRent(Rent rent) {
this.rent = rent;
//生成得到代理美
public object getProxy(){
return Proxy .newProxyInstance(this. getClass(). getClassLoader(),rent . getClass(). getInterfaces(). h: this);
//处理代理实例,并返回结果
public object invoke(object proxy, Method method, Object[] args) throws Throwable d
//动态代理的本质。就是使用反射机制实现!
object result = method . invoke(rent, args);
]
return resu1t;

测试

public class Client {
public statlc vo1d main(String[] args) {
//真实角色.
Host host = new Host();
//代理角色:现在没有
ProxyInvocationHandler pih = new ProxyInvocationHand1er();
//.通i调川程序处理角色来处理我们要调川的接11对象!
pih. setRent(host);
Rent proxy = (Rent) pih. getProxy();//这里的proxy就是动态生成的。我们并没有写
proxy . rent();
}

通用类:

//等我们会用这个类,自动生成代理类!
public class ProxyInvoct ionHandler implements InvocationHandler {
//被代理的接11
private object target;
public void setTarget(Object target) {
this.target = target;
}
//生成得到代理类
public object getProxy(){
return Proxy .newProxyInstance(this. getClass(). getClassloader(),
target .getC1ass(). getInterfaces(). h: this);
}
1/处理代理文阙,并题回结梁:
public object invoke(0bject proxy, Method method, object[] args) throws Throwable {
1og(method. getName());
object result = method. invake(target, args);
return result;
}
public void 1og(String msg){
System. out . print1n("执行了"+msg+"方法" );
}

测试:

public class Client {
public static void main(String[] args) {
//真实角色
UserServiceImpl userService = new UserServiceImp1();
//代理角色,不存在
ProxyInvocationHandler pih = new ProxyInvocationHandler();
pih. setTarget(userService); // 设置要代理的对象
//动态生成代理类
UserService proxy = (UserService) pih. getProxy();
proxy . delete();
}
}

动态代理的好处:
●可以使真实角色的操作更加纯粹!不用去关注一 些公共的业务
●公共也就就交给代理角色!实现了业务的分工!
●公共业务发生扩展的时候,方便集中管理!
●一个动态代理类代理的是一个接口, 一般就是对应的一类业务
●一个动态代理类可以代理多个类,只要是实现了同一个接口即可!

12、AOP的实现

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

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-yCLCMFlb-1665910219497)(C:\Users\Administrator\AppData\Roaming\Typora\typora-user-images\image-20221016153150649.png)]

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-nCWlFReC-1665910219498)(C:\Users\Administrator\AppData\Roaming\Typora\typora-user-images\image-20221016153319665.png)]

<dependencies>
<1-- https://mvnrepository. com/artifact/org. aspectj/aspectjwe
<dependency>
<groupId>org . aspectj</ groupId>
<artifactId>aspectjweaver</ artifactId>
<version>1.9. 4</version>
</ dependency>
</ dependencies>

方式一:使用spring的接口【主要是SpringAPI接口实现】

public class Log implements MethodBeforeAdvice {
//method:|要执 行的月标对象的方法
//args:多数
//target: 1标对象
public void before(Method method, 0bject[] args, object target) throws Throwable {
System. out . print1n(target . getClass() . getName( )+"的“+method. getName()+"被执行了");
}
public class MyTest
public static void main(string[] args) {
ApplicationContext context = new ClassPathXmlApplicationContext( configLocation: " applicationContext . xml" );
//动态代理代理的是接口
UserService userService = (UserService) context. getBean( s: "userService");
userService. add();
}
}

aop配置

<!--注册bean-->
<bean id="userService" class=" com. kuang。service .UserServiceImp1"/>
<bean id="1og" class=" com. kuang.1og.Log"/>
<bean id="afterlog" class=" com . kuang。log .AfterLog"/>
<!--配置Aop:需要导入aop的约束-->
<aop :config>
<!--切入点: expression: 表达式。execution( 要执行的位置! *****)-->
<aop:pointcut 1d="pointcut" expression-"execution(* com . kuang. service. UserServiceImp1.*(..))"/>
</aop :config>

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

public class DiyPointCut {
public vold before(){
System. out . printin-(="======方法执行=======");
}
public void after()[
System. out . print1n(" ======方法执行后=======" );
    }
    }

注册类

<!--方式二:自定义美--> .
<bean 1d="diy" class="com. kuang. diy. DiyPointcut"/>
<aop:config>
<!-月定义切面,ref 要引用的类-->
kaop:aspect ref="diy">
<!--切入点-->
<aop: pointcut id-" point" expression= "execution(* com. kuang. service. UserServiceImpl. *(..))"/>
<!--通知-->
<aop: before method="before" pointcut -ref=" point"/>
<aop:after method=" after" pointcut -ref= "point"/>
</ aop:aspect>
</aop :conf1g>
public class MyTest {
public static void main(string[] args) {
ApplicationContext context = new ClassPathXmlApplicationContext( configLocation: " applicationContext . xml" );
//动态代理代理的是接11:兹意点
UserService userService = (UserService) context. getBean( s: "userService");
userService . add(;|
}

方式三:使用注解

@Aspect:标注这个类是一个切面


//方式三:使用注解方式 实现AOP
import org . aspectj。lang. annotation . Aspect;
import org. aspectj .1ang. annotation.Before;
@Aspect //标注这个类是一-个 切面
public class AnnotationPointCut {
 @Before(" execution(* com. kuang . service.UserServiceImp1.*(.))") 
public void before( ){
system. out . printn("====方法执行前=====");
}
}

<!--方式三-->
<bean 1d=" annatatlonPointCut" class="com. kuang . diy. AnnotatlonPolntCut" />
<!--开启注解支持! -->
<aop: aspectj - autoproxy/>

@Around

//在环绕增强中,我们可以给定一个参数。 代表我们要获取处型切入的点:
@Around( " execution(* com. kuang . service . UserServiceImpl. *(..))")
public vold around(ProceedingJoinPoint jp) throws Throwable {
System. out . println("环绕前");
//执行方法
object proceed = jp . proceed();
system. out . println("环绕后");
}

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-JXkE7fUw-1665910219499)(C:\Users\Administrator\AppData\Roaming\Typora\typora-user-images\image-20221016160054743.png)]

13、整合MyBatis

步骤:

1、导入相关Jar包

junit

mybatis

mysql

spring

aop

mybatis-spring

<dependencies>
<dependency>
<groupId>junit</ groupId>
<artifactId>junit</artifactId>
<version>4.12</version>
</dependency>
<dependency>
<groupId>mysq1</ groupId>
<artifactId>mysq1-connector- java</artifactId>
<version>5.1.47</vers ion)
</dependency>
<dependency>
<groupId>org. mybatis</ groupId>
<artifactId>mybatis</artifactId>
<vers1on>3.5.2</vers1on>
</dependency>
<dependency>
<groupId>org. springframework</ groupId>
<artifactId>spring-webmvc</ artifactId>
<version>5.1.9. RELEASE</version>
</dependency>
<!--Spring操作最辉库的话,还需要一个spring-jdbc-->
<dependency>
<groupId>org . springframework</ groupId>
<artifactId>spring-jdbc</ artifactId>
<version>5.1.9. RELEASE</version>
</dependency>
<dependency>
groupId>org . aspectj</ groupId>
<artifactId>aspectjweaverk/ artifactId>
<version>1.8.13</version)
</dependency>
    <dependency>
<groupId>org . mybatis</ groupId>
<artifactId>mybatis-spring</artifactId>
<version>2.0.2< /version>
</ dependency>
</ dependencies>

2、编写配置类mybatis-config.xml

<?xml version="1.0" encoding="UTF-8" ?>
< !DOCTYPE configuration
PUBLIC "-/ /mybatis. org//DTD Config 3.0//EN"
"http://mybatis .org/dtd/ mybatis-3-config.dtd">
<!--configuration核心配置文件-->
< configuration>
<environments default= " development">
<environment id=" development">
<transactionManager type="JDBC"/>
<dataSource type="POOLED" >
<property name="driver" value=" com. mysq1. jdbc . Driver"/>
<property name="url" value="jdbc :mysql : //localhost :3306/mybatis ?useSSL
< property name="username" value= "root"/ >
<property name="password" value="123456"/>
</dataSource>
< /environment> I
</ environments>
</ configuration>

3、测试

13.1、mybatis-spring

applicationContext.xml

<?xm1 version="1.0" encoding="UTF-8"?>
<beans xmIns="http: //www. springframework . org/ schema/beans"
◎◎?00
xmlns:xsi="http://ww.w3. org/2001/XML Schema- instance"
xmIns :aop= "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">
<!--DataSource:使用Spring的数据源替换Mybatis的配置c3pθ dbcp druid
我们这里使用Spring提供的JDBC : org. springframework. jdbc. datasource
-->
<bean id="datasource" class="org. springfr amework. jdbc . datasource. DriverManagerDataSource">
<property name=" driverClassName" value="com. mysq1. jdbc . Driver"/>
<property name="ur1" value= "jdbc :mysq1://localhost: 3306/mybatis ?useSSL=true&amp; useUnicode=true&amp; characterEncoding=UTF-8"/>
<property name="username" value="root"/>
<property name="password" value="123456"/>
</bean>
<! --sqlSessionFactory-->
<bean id="sqlSessionFactory" class="org . mybatis . spring . SqlSessionFactoryBean">
<property name="dataSource" ref="dataSource" />
    <!--.绑定Mabatis配置文件-->
<property name=" configuration" value=" classpath:mybatis-config . xml"/>
<property name=" mapperLocations" value=" classpath: com/kuang/ mapper/* . xm1"/>
</bean>
    <!--SqlSessionTemplate:就是我们使用的sqlSession-->
<bean id="sq1Session" c1ass="org. mybatis。spring. Sq1SessionTemplate">
<!--只能使用构造器注入sqlSessionFactory,因为它没有set方法-->
constructor-arg index "0" ref="sqlSessionFactory"/>
</bean>
</beans>

14、声明式事务

1、回顾事务

把一组业务当成一个义务处理,要么都成功,要么都失败!

事务在项目开发中十分的重要,设计到数据的一致性问题,不能马虎!

确保完整性和一致性!

事务的ACID原则:

原子性

一致性

隔离性:多个业务操作同一个资源,防止数据损坏

持久性:事务一旦提交,无论系统发生什么问题,结果都不会被影响,被持久化的写到存储器中!

2、Spring中的事务管理

声明式事务:AOP

编程式事务:

<!--配置声明式事务-->
<bean id="transactionManager" class= "org. springframework . jdbc . datasource . DataSourceTransactionManager">
<property name= "dataSource" ref="dataSource"/>
</bean>
<!--结合AOP实现事务的织入-->
<!--配置事务通知; --> 
<tx:advice id="txAdvice" transaction-manager= "transactionManager">
<!--给那些方法配置事务-->
<!--配置事务的传播特性: new propagation= -->
<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-on1y="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>

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-NzGuvdRD-1665910219499)(C:\Users\Administrator\AppData\Roaming\Typora\typora-user-images\image-20221016164430054.png)]

思考:
为什么需要事务?
●如果不配置事务,可能存在数据提交不一致的情况下;
●如果我们不在SPRING中去配置声明式事务,我们就需要在代码中手动配置事务!

1、回顾事务

把一组业务当成一个义务处理,要么都成功,要么都失败!

事务在项目开发中十分的重要,设计到数据的一致性问题,不能马虎!

确保完整性和一致性!

事务的ACID原则:

原子性

一致性

隔离性:多个业务操作同一个资源,防止数据损坏

持久性:事务一旦提交,无论系统发生什么问题,结果都不会被影响,被持久化的写到存储器中!

2、Spring中的事务管理

声明式事务:AOP

编程式事务:

<!--配置声明式事务-->
<bean id="transactionManager" class= "org. springframework . jdbc . datasource . DataSourceTransactionManager">
<property name= "dataSource" ref="dataSource"/>
</bean>
<!--结合AOP实现事务的织入-->
<!--配置事务通知; --> 
<tx:advice id="txAdvice" transaction-manager= "transactionManager">
<!--给那些方法配置事务-->
<!--配置事务的传播特性: new propagation= -->
<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-on1y="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>

[外链图片转存中…(img-NzGuvdRD-1665910219499)]

思考:
为什么需要事务?
●如果不配置事务,可能存在数据提交不一致的情况下;
●如果我们不在SPRING中去配置声明式事务,我们就需要在代码中手动配置事务!
●事务在项目的开发中十分重要,设计到数据的一致性和完整性问题,不容马虎!

  Java知识库 最新文章
计算距离春节还有多长时间
系统开发系列 之WebService(spring框架+ma
springBoot+Cache(自定义有效时间配置)
SpringBoot整合mybatis实现增删改查、分页查
spring教程
SpringBoot+Vue实现美食交流网站的设计与实
虚拟机内存结构以及虚拟机中销毁和新建对象
SpringMVC---原理
小李同学: Java如何按多个字段分组
打印票据--java
上一篇文章      下一篇文章      查看所有文章
加:2022-10-17 12:18:51  更:2022-10-17 12:19:07 
 
开发: C++知识库 Java知识库 JavaScript Python PHP知识库 人工智能 区块链 大数据 移动开发 嵌入式 开发工具 数据结构与算法 开发测试 游戏开发 网络协议 系统运维
教程: HTML教程 CSS教程 JavaScript教程 Go语言教程 JQuery教程 VUE教程 VUE3教程 Bootstrap教程 SQL数据库教程 C语言教程 C++教程 Java教程 Python教程 Python3教程 C#教程
数码: 电脑 笔记本 显卡 显示器 固态硬盘 硬盘 耳机 手机 iphone vivo oppo 小米 华为 单反 装机 图拉丁

360图书馆 购物 三丰科技 阅读网 日历 万年历 2025年3日历 -2025/3/10 17:16:36-

图片自动播放器
↓图片自动播放器↓
TxT小说阅读器
↓语音阅读,小说下载,古典文学↓
一键清除垃圾
↓轻轻一点,清除系统垃圾↓
图片批量下载器
↓批量下载图片,美女图库↓
  网站联系: qq:121756557 email:121756557@qq.com  IT数码