Spring基础个人知识点总结

1、Spring

1.简介

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

2.优点

  • Spring是一个免费的、开源框架(容器)
  • Spring是一个轻量级、非入侵式框架
  • 控制反转(IOC)、面向切面编程(AOP)
  • 支持事务的处理,对框架整合的支持

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

3.组成

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-Rv5KlX9Q-1602250310841)(img/202009271028.png)]

核心容器(Spring Core)

核心容器提供Spring框架的基本功能。Spring以bean的方式组织和管理Java应用中的各个组件及其关系。Spring使用BeanFactory来产生和管理Bean,它是工厂模式的实现。BeanFactory使用控制反转(IoC)模式将应用的配置和依赖性规范与实际的应用程序代码分开。

应用上下文(Spring Context)

Spring上下文是一个配置文件,向Spring框架提供上下文信息。Spring上下文包括企业服务,如JNDI、EJB、电子邮件、国际化、校验和调度功能。

Spring面向切面编程(Spring AOP)

通过配置管理特性,Spring AOP 模块直接将面向方面的编程功能集成到了 Spring框架中。所以,可以很容易地使 Spring框架管理的任何对象支持 AOP。Spring AOP 模块为基于 Spring 的应用程序中的对象提供了事务管理服务。通过使用 Spring AOP,不用依赖 EJB 组件,就可以将声明性事务管理集成到应用程序中。

JDBC和DAO模块(Spring DAO)

JDBC、DAO的抽象层提供了有意义的异常层次结构,可用该结构来管理异常处理,和不同数据库供应商所抛出的错误信息。异常层次结构简化了错误处理,并且极大的降低了需要编写的代码数量,比如打开和关闭链接。

对象实体映射(Spring ORM)

Spring框架插入了若干个ORM框架,从而提供了ORM对象的关系工具,其中包括了Hibernate、JDO和 IBatis SQL Map等,所有这些都遵从Spring的通用事物和DAO异常层次结构。

Web模块(Spring Web)

Web上下文模块建立在应用程序上下文模块之上,为基于web的应用程序提供了上下文。所以Spring框架支持与Struts集成,web模块还简化了处理多部分请求以及将请求参数绑定到域对象的工作。

MVC模块(Spring Web MVC)

MVC框架是一个全功能的构建Web应用程序的MVC实现。通过策略接口,MVC框架变成为高度可配置的。MVC容纳了大量视图技术,其中包括JSP、POI等,模型来有JavaBean来构成,存放于m当中,而视图是一个街口,负责实现模型,控制器表示逻辑代码,由c的事情。Spring框架的功能可以用在任何J2EE服务器当中,大多数功能也适用于不受管理的环境。Spring的核心要点就是支持不绑定到特定J2EE服务的可重用业务和数据的访问的对象,毫无疑问这样的对象可以在不同的J2EE环境,独立应用程序和测试环境之间重用

4.拓展

​ 现代化的Java开发就是基于Spring的开发

SpringBoot(构建一切)—>SpringCloud(协调一切)—>SrpingCloudDataFlow(连接一切)

  • SpringBoot
    • 一个快速开发的脚手架
    • 基于SpringBoot可以快速的开发单个微服务
    • 约定大于配置
  • Spring Cloud
    • Spring Cloud 是基于SpringBoot实现的

而大多数公司使用SpringBoot进行快速开发,学习SpringBoot的前提则需要完全掌握Spring、SpringMVC(承上启下的作用)

弊端:发展太久,违背了原来的理念,配置繁琐“配置地狱”

2、IOC原理

​ 创建了一个UserDao接口,并创建了两个实现类

//接口
public interface UserDao {
    public void getUserDao();
}
//接口的两个实现类
public class OracleImpl implements UserDao{
    public void getUserDao() {
        System.out.println("Oracle");
    }
}
public class MysqlImp implements UserDao{
    public void getUserDao() {
        System.out.println("Mysql");
    }
}
//测试类
public class IOCtest {
    private UserDao userDao;
    //开发人员手动更改,非常麻烦
    private UserDao userDao = new MysqlImp()/private UserDao userDao = new OracleImp()
    //有了这个方法则可以手动接受用户创建的对象实现调用特定的方法
    public void setUserDao(UserDao userDao){
        this.userDao=userDao;
    }
    public static void main(String[] args) {
        UserDao userDao = new MysqlImp();
        userDao.getUserDao();
        userDao= new OracleImpl();
        userDao.getUserDao();
    }
}

IOC本质

​ **控制反转(Inversion of Control)是一种设计思想,DI(依赖注入)是实现IoC的一种方法;**我们使用面向对象编程,对象的创建和对象之间的依赖关系完全硬编码在程序中,对象的创建是由程序自己控制的.控制反转就是将对象的创建转移给了第三方.

IOC是:获得依赖对象的方式反转了

硬编码:是将数据直接其纳入到程序或其他可执行程序或其他可执行对象的源代码中的软件开发时间,与外部获取数据或在运行时生成数据不同。硬编码数据通常只能通过编辑源代码或重新编译可执行文件来修改。

​ 采用XML方式配置Bean的时候,Bean的定义信息是和实现分离的,而采用注解的方式可以把两者合为一体,Bean的定义信息直接以注解的形式定义在实现类中,从而达到了零配置的目的。

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

3、HelloSpring

​ 环境配置

​ 1.创建Hello类

public class Hello {
    private String str ;
    //若不存在无参构造方法则 xml文件中bean标签中的class属性会报错
    public Hello() {
    }
    public Hello(String str) {
        this.str = str;
    }
    public String getStr() {
        return str;
    }
    //利用set方法注入,此方法必须存在否则报错
    public void setStr(String str) {
        this.str = str;
    }
    @Override
    public String toString() {
        return "Hello{" +
                "str='" + str + '\'' +
                '}';
    }
}

​ 2.创建beans.xml配置文件


<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="Hello" class="com.pojo.Hello">
        <property name="str" value="spring">property>
    bean>
beans>

​ 3.导入依赖

<dependency>
            <groupId>org.springframeworkgroupId>
            <artifactId>spring-webmvcartifactId>
            <version>5.2.0.RELEASEversion>
dependency>

​ 4.测试

public class TestHelloSpring {
    public static void main(String[] args) {
        //参数为配置文件名,也可以为多个配置文件
        ApplicationContext applicationContext =new ClassPathXmlApplicationContext("beans.xml");
        //参数名为bean标签的id名,也可以理解为Srping已经创建了对象,调用方法在此处获得对象
        Hello hello = (Hello) applicationContext.getBean("Hello");
        System.out.println(hello.toString());
    }
}

注: value为具体的值,基本数据类型

​ ref为Spring容器中已经创建的对象(为引用数据类型的成员变量进行赋值)

<bean id="Mysql" class="com.TestIOC.MysqlImp"></bean>
<bean id="IOCtest" class="com.TestIOC.IOCtest">
        <property name="userDao" ref="Mysql"/>
</bean>

4、Spring创建对象

​ Spring容器创建对象需要有无参构造方法

​ 使用有参构造方法创建对象;

测试实体类

public class User {
    private String name;
    public User(String name) {
        this.name=name;
        System.out.println("有参构造方法");
    }
    public String getName() {
        return name;
    }
    public void setName(String name) {
        this.name = name;
    }
    public String toString() {
        return "User{" +
                "name='" + name + '\'' +
                '}';
    }
}

第一种方法:使用索引(下标)

<bean id="user" class="com.pojo.User">
        <constructor-arg index="0" value="jack">constructor-arg>
    bean>

第二种方法:使用数据类型/多个属性

<bean id="user" class="com.pojo.User">
        <constructor-arg type="java.lang.String" value="jack">constructor-arg>
    bean>

第三种方法:参数名字

<bean id="user" class="com.pojo.User">
        <constructor-arg name="name" value="jack">constructor-arg>
    bean>

总结:在配置文件加载的时候,容器中管理对象已经初始化了,若多个属性则多个属性标签按顺序进行赋值

5、Spring配置

1.别名配置

 <alias name="user" alias="afajkdfldsj">alias>

测试:

User user = (User) context.getBean("user");
User user1 = (User)context.getBean("afajkdfldsj");
System.out.println(user==user1); //ture

可知通过id与别名都可以获得对象且获得的对象为同一个对象因为内存地址相同

2.Bean配置


<bean id="user" class="com.pojo.User" name="u1,u2,u3">

测试

User user = (User) context.getBean("u1");

3.import

​ 一般用于团队开发,它可以将多个配置文件导入合并为一个

​ bean的配置文件名因为 applicationContext.xml,若有多人多个beans.xml,则可以在总配置文件applicationContext文件中全部导入合并为一个配置文件,相同内容也会合并

6、DI依赖注入

1.set注入☆☆☆

环境搭配

创建两个实体类:

​ 复杂类型:Address类

public class Address {
    private String address;

    public String getAddress() {
        return address;
    }

    public void setAddress(String address) {
        this.address = address;
    }
}

​ 真实测试对象:Student类(使用了注解,导入包即可)

@Data
@AllArgsConstructor
@NoArgsConstructor
public class Student {
    private String name;
    private Address address;
    private String[] books;
    private List<String> hobbys;
    private Map<String,String>card;
    private Set<String>games;
    private String wife;
    private Properties info;
}

<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">
    <bean id="Address" class="com.pojo.Address">bean>
    <bean id="Student" class="com.pojo.Student">
        
        <property name="name" value="张三">property>
        
        <property name="address" ref="Address"/>
        
        <property name="books">
            <array>
                <value>红楼梦value>
                <value>三国演义value>
            array>
        property>
        
        <property name="hobbys">
            <list>
                <value>音乐value>
                <value>学习value>
            list>
        property>
        
        <property name="card">
            <map>
                <entry key="身份证" value="11111****22222">entry>
                <entry key="银行卡" value="123456">entry>
            map>
        property>
        
        <property name="games">
            <set>
                <value>LOLvalue>
                <value>Wzryvalue>
            set>
        property>
        
        <property name="wife">
            <null>null>
        property>
        
        <property name="info">
            <props>
                <prop key="学号">33190101111prop>
                <prop key="性别">男性prop>
            props>
        property>
    bean>
beans>

​ 总结:

  1. property标签相同,name属性为变量名
  2. property标签内部添加相应子标签例如 set、list、map等
  3. 除了map,props,null,其他标签内部写入value标签添加值即可
    1. map标签内部添加 entry设置 key、value值
    2. props标签内部添加prop,其中value值在prop标签对之内
    3. null标签内部直接添加null标签对即可

测试

public class testDI {
    public static void main(String[] args) {
        ApplicationContext Context = new ClassPathXmlApplicationContext("ApplicationContext.xml");
        Student student = (Student) Context.getBean("Student");
        System.out.println(student.toString());

    }
}

2.拓展注入

1.P命名空间注入

创建实体类User

@Data
@NoArgsConstructor
@AllArgsConstructor
public class User {
    private String name;
    private int age;
}

配置XML文件


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

<bean id="User" class="com.pojo.User" p:age="11" p:name="张三" />

测试

 public void testDI(){
        ApplicationContext Context = new ClassPathXmlApplicationContext("BeanUsers.xml");
        User user = Context.getBean("User", User.class);
        System.out.println(user);
    }

2.C命名空间注入

配置XML文件

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

<bean id="User01" class="com.pojo.User" c:name="李四" c:age="18">bean>

测试

 public void testDi(){
        ApplicationContext Context = new ClassPathXmlApplicationContext("BeanUsers.xml");
        User user = Context.getBean("User01", User.class);
        System.out.println(user);
    }

3.bean作用域

​ 1.单例模式(Spring默认机制)

<bean id="User" class="com.pojo.User" p:age="11" p:name="张三" scope="singleton"/>

​ 无论从容器中获得多少对象,对象都为同一个(内存地址相同)

​ 2.原型模式

<bean id="User" class="com.pojo.User" p:age="11" p:name="张三" scope="prototype"/>

​ 每一次从容器中获得的对象都不是同一个

​ 3.其与的request、session、application,这些只能在web开发中使用到

7、Bean的自动装配

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

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

在Spring中有三种自动装配的方式:

  1. 在xml中显性的配置
  2. 在java中显示配置
  3. 隐式的自动装配bean(重要)

1.配置环境

//创建猫咪类
public class Cat {
    public void shout(){
        System.out.println("喵喵喵~");
    }
}
------------------------------------
//创建狗狗类
public class Dog {
    public void shout(){
        System.out.println("汪汪汪~");
    }
}
------------------------------------
//创建人类
@Data
@NoArgsConstructor
@AllArgsConstructor
public class People {
    private Dog dog;
    private Cat cat;
    private String name;
}


<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">
    <bean id="Dog" class="pojo.Dog"/>
    <bean id="Cat" class="pojo.Cat"/>
    <bean id="People" class="pojo.People">
        <property name="dog" ref="Dog"/>
        <property name="cat" ref="Cat"/>
        <property name="name" value="憨批"/>
    bean>
beans>

2.自动装配

1.1自动装配 byName

<bean id="dog" class="pojo.Dog"/>
<bean id="cat" class="pojo.Cat"/>
    
<bean id="People" class="pojo.People" autowire="byName">
     <property name="name" value="憨批"/>
 bean>

1.2 自动装配 byType

 <bean id="Dog" class="pojo.Dog"/>
  <bean class="pojo.Cat"/>
    
    <bean id="People" class="pojo.People" autowire="byType">
        <property name="name" value="憨批"/>
    bean>

8、注解自动装配

1. @Autowired☆☆☆

1.1 导入约束:


<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"
       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"> 
    <context:annotation-config/>
beans>

1.2 配置注解支持:context:annotation-config/

​ 1.3 @Autowired

直接在属性上使用,也可以在set方法上使用

​ 使用注解我们可以不再编写set方法,前提是自动装配的属性必须在IOC(Spring)容器中存在,且名字复合byName

​ 注:

  1. @Autowired默认是按照类型来装配,因为即使bean名字与对象属性名不同也没有报错而正常运行
  2. 若有多个类型相同,则按照名字进行自动装配
  3. 若有多个类型相同且名字都不相同的bean,再使用 **@Qualifier(value = “xxx”)**指明自动装配那个bean
<bean id="Dog111" class="pojo.Dog"/>
 <bean id="Dog222" class="pojo.Dog"/>
@Autowired
@Qualifier(value = "Dog222")
private Dog dog;

2. @Resource

​ 这个注解是Java中的注解,不是Spring中的注解。 @Resource = @Autowired+@Qualifier

​ @Resource(name = “xxx”)可以传入值,作用与@Qualifier相同,在有两个数据类型相同且名字与对象中属性名不同的情况下指定bean-id的装配


总结:@Resource与@Autowired的相同与相异

  • 都是用来自动装配,都可以放在属性上
  • @Autowired首先按照类型来自动装配,若类型 > 1,则按照名字进行自动装配,若类型>1且名字不同报错
  • @Resource首先按照byName自动装配,若名字不同再按照类型自动装配,若二者皆匹配不上就会报错

9、Spring注解开发

1.导入依赖与约束

​ 包扫描:这个包下的所有注解将会生效(支持约束的第二种方式)


<context:component-scan base-package="pojo"/>
<context:annotation-config/>

2.bean注入:@Component

@Component //译为组件,放在类说明此类已经被Spring管理,bean-id默认名为类名首字母小写
//等价于 	
public class User {
    public String name="张三";
}

3.属性注入: @Value(“xxx”)

@Value("张三")
//只能注解简单类型,DI注入建议使用配置文件
public String name;
---------------------------------------
//也可以放在set方法上
@Value("张三")
public void setName(String name) {
    this.name = name;
}

4.衍生注解

​ @Component有几个衍生注解,在web开发中,会按照mvc三层架构分层

  • dao :@Repository
  • service: @Service
  • controller: @Controller

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

5.自动装配

​ @Autowired 、@Qualifier 、@Resource

6.作用域

@Scope("prototype")  //原型模式
@Scope("singleton")  //单例模式

7.小结

​ xml与注解:

  • xml更加万能,适用于所有场合,维护简单方便
  • 注解不是自己的类是用不了,维护相对复杂

​ xml与注解最佳实践

  • xml用来管理bean
  • 注解只负责属性的注入
  • 必须让注解生效,开启相应注解的支持

10、Java的方式配置Spring

这种方式放弃了使用applicationContext.xml配置文件,使用java配置类

//普通实体类
@Component //说明此类已经注入Spring容器中被接管
public class User {
    @Value("张三")
    private String name;
    public User() {
    }
    public void setName(String name) {
        this.name = name;
    }
}
//Java配置类
@ComponentScan("pojo")//扫描包
@Configuration //类似于beans
@Import(xxx.class) //相当于 import,引入其他配置类 XXXConfig.xml
public class LiangCofig {
    @Bean //注册一个bean,就相当于我们之前写的bean标签
          //方法的名字为 bean-id;返回值为bean标签中的class属性
    public User getUser(){
        return new User();
    }
}
//测试类
ApplicationContext context = new AnnotationConfigApplicationContext(LiangCofig.class);
User bean = context.getBean("getUser", User.class);
System.out.println(bean.toString());

个人小结

  • @Configuration:类被标记意味着此类是配置类,形同 applicationContext.xml文件
  • @Import(xxx.class:将其他配置类引入
  • @ComponentScan(""):扫描包
  • @Bean:相当于bean标签,创建对象

@Component与@bean的区别:

@Component:通过classpath扫描实现实体自动检测,通过Srping容器创建对象

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-XrIoLeDZ-1602250310847)(img/20201003110739789.png)]

@bean只能用来声明一个单独的bean,告诉Spring这个方法将会返回一个对象,这个对象要注册为Spring应用上下文中的。bean通常方法体中包含了最终产生bean实例的逻辑。但是Bean比Component的自定义性更强。可以实现一些Component实现不了的自定义加载类。

11、代理模式

1.静态代理

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-QRYoia1e-1602250310850)(img/image-20201003150128234.png)]

角色分析:

  • 抽象角色:一般使用接口或抽象类解决
  • 真实角色:被代理的角色
  • 代理角色:代理真实角色,代理真实角色会做一些附属操作
  • 客户:访问代理角色的

优点:

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

缺点:一个真实角色就会产生一个代理,当真是角色过多时开发效率会降低

2.动态代理

1.实例演示

//真实角色
public class Host implements Rent{
    public void rent() {
        System.out.println("租房子");
    }
}
//抽象角色
public interface Rent {
    public void rent();
}
//没有代理角色,可以创建代理角色
public class ProxyInvo implements InvocationHandler {
    //接口属性
    private Rent rent;

    public void setRent(Rent rent) {
        this.rent = rent;
    }

    //获取代理对象
    //三个参数,一个是加载类,一个是接口的类,一个是当前对象
    public Object getProxy(){
        return Proxy.newProxyInstance(this.getClass().getClassLoader(),
                                      rent.getClass().getInterfaces(),this);
    }

    public Object invoke(Object proxy, Method method, Object[] args) throws Throwable {
        //动态代理的本质,就是使用反射机制调用方法
        this.sendMesg();//直接调用
        Object invoke = method.invoke(rent, args);
        return invoke;
    }
    //创建额外的功能
    public void sendMesg(){
        System.out.println("房子存活充足,可以租赁");
    }
}

//测试
public class Client {
    public static void main(String[] args) {
        //创建真实角色对象
        Host host =new Host();
        //创建代理对象
        ProxyInvo invo = new ProxyInvo();
        //传入需要代理的对象
        invo.setRent(host);
        //获得代理对象
        Rent proxy = (Rent) invo.getProxy();
        //调用方法
        proxy.rent();
    }
}

总结:

​ 代理模式没有代理者,只有被动态创建的类似于代理者的类

​ 代理模式需要了解两个:proxy类、InvocationHandler接口

​ 代理者需要真实角色,抽象角色

12、AOP

AOP简介:

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-03YapaW7-1602250310853)(img/image-20201003154945272.png)]

方式一:使用Spring API接口

​ 1.导包

<dependency>
            <groupId>org.aspectjgroupId>
            <artifactId>aspectjweaverartifactId>
            <version>1.9.6version>
dependency>
---------------------------------------------------------------------------------------------------------
<dependency>
        <groupId>org.aspectjgroupId>
        <artifactId>aspectjrtartifactId>
        <version>1.9.4version>
dependency>
<dependency>
            <groupId>aopalliancegroupId>
            <artifactId>aopallianceartifactId>
            <version>1.0version>
dependency>

​ 2.导入aop依赖并配置文件


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

    <bean id="log" class="com.Log.Log"/>
    <bean id="logAfter" class="com.Log.LogAfter"/>
    <bean id="userService" class="com.Service.UserServiceImp"/>
    <aop:config>
        
        
        <aop:pointcut id="poincut" expression="execution(public void com.Service.UserServiceImp.*(..))"/>
        
        <aop:advisor advice-ref="log" pointcut-ref="poincut"/>
        <aop:advisor advice-ref="logAfter" pointcut-ref="poincut"/>
    aop:config>
beans>

​ 3.Log类与LogAfter类

public class Log implements MethodBeforeAdvice {
    public void before(Method method, Object[] args, Object target) throws Throwable {
        System.out.println(target.getClass().getName()+"的"+method.getName()+"执行了");
    }
}
------------------------------------------------------------------------------------------
public class LogAfter implements AfterReturningAdvice {
    public void afterReturning(Object returnValue, //执行方法后的返回值
                               Method method, //执行的方法
                               Object[] args,//方法参数
                               Object target) //目标类
        throws Throwable {
        System.out.println(target.getClass().getName()
                           +"的"+method.getName()
                           +"执行了,返回结果为:"
                           +returnValue);
    }
}

​ 4.测试

public class TestAop {
    public static void main(String[] args) {
        ApplicationContext context = new ClassPathXmlApplicationContext("applicationContext.xml");
        //动态代理为接口,实现类则报错,参数名为实现类,强转为接口
        UserService userService = context.getBean("userService", UserService.class);
        userService.add();
    }
}

个人理解:

​ 只是增加了日志,程序执行了指定方法之前打印日志中的内容,xml文件负责将日志放在指定方法上。日志方法需要实现特定接口

方式二:自定义类


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

    <bean id="log" class="com.Log.Log"/>
    <bean id="logAfter" class="com.Log.LogAfter"/>
    <bean id="userService" class="com.Service.UserServiceImp"/>
    <bean id="diyAop" class="com.DIY.diyAop"/>
    <aop:config>
        <aop:aspect ref="diyAop">
            
            <aop:pointcut id="point" expression="execution(* * com.Service.UserServiceImp.*(..))"/>
            
            <aop:before method="begin" pointcut-ref="point"/>
            <aop:after method="over" pointcut-ref="point"/>
        aop:aspect>
    aop:config>
beans>

方式三:使用注解

@Aspect //代表切入面
public class AnnotationAop {
    @Before("execution(public void com.Service.UserServiceImp.*(..))") 
    public void before(){
        System.out.println("begin....");
    }
    @After("execution(public void com.Service.UserServiceImp.*(..))")
    public void after(){
        System.out.println("over....");
    }
}
<bean id="annotationAop" class="com.DIY.AnnotationAop"/>
<aop:aspectj-autoproxy/> //开启注解支持

13、整合Mybatis

1.环境搭建

<dependencies>
    	
        <dependency>
            <groupId>org.springframeworkgroupId>
            <artifactId>spring-webmvcartifactId>
            <version>5.2.0.RELEASEversion>
        dependency>
    --------------------------------------------------------------
    	
        <dependency>
            <groupId>junitgroupId>
            <artifactId>junitartifactId>
            <version>4.12version>
        dependency>
    --------------------------------------------------------------
        
    	<dependency>
            <groupId>org.aspectjgroupId>
            <artifactId>aspectjweaverartifactId>
            <version>1.9.6version>
        dependency>

    ---------------------------------------------------------------
	    
        <dependency>
            <groupId>mysqlgroupId>
            <artifactId>mysql-connector-javaartifactId>
            <version>5.1.47version>
        dependency>
    ---------------------------------------------------------------
        
    	<dependency>
            <groupId>org.mybatisgroupId>
            <artifactId>mybatisartifactId>
            <version>3.5.2version>
        dependency>
    --------------------------------------------------------------
    	
        <dependency>
            <groupId>org.springframeworkgroupId>
            <artifactId>spring-jdbcartifactId>
            <version>5.1.9.RELEASEversion>
        dependency>
    -------------------------------------------------------------
	    
        <dependency>
            <groupId>org.mybatisgroupId>
            <artifactId>mybatis-springartifactId>
            <version>2.0.2version>
        dependency>
    dependencies>

2.第一种方式

2.1 配置xml文件


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

    
    
    <bean id="dataSource" class="org.springframework.jdbc.datasource.DriverManagerDataSource">
        <property name="driverClassName" value="com.mysql.jdbc.Driver"/>
        <property name="url" value="jdbc:mysql://localhost:3306/mybatis?useSSL=false&
                                    useUnicode=true&characterEncoding=utf-8"/>
        <property name="username" value="root"/>
        <property name="password" value="123"/>
    bean>
    
    <bean id="sqlSessionFactory" class="org.mybatis.spring.SqlSessionFactoryBean">
        <property name="dataSource" ref="dataSource"/>
        
        <property name="configLocation" value="classpath:mybatis-config.xml"/>
        
        <property name="mapperLocations" value="classpath:com/dao/UserMapper.xml"/>
    bean>
    
    <bean id="sqlSession" class="org.mybatis.spring.SqlSessionTemplate">
        
        <constructor-arg name="sqlSessionFactory" ref="sqlSessionFactory"/>
    bean>
    
    <bean id="userMapper" class="com.dao.UserMapperImpl">
        <property name="sqlSession" ref="sqlSession"/>
    bean>
beans>

2.2 添加类实现接口

public class UserMapperImpl implements UserMapper{
    private SqlSessionTemplate sqlSession;

    public void setSqlSession(SqlSessionTemplate sqlSession) {
        this.sqlSession = sqlSession;
    }

    public List<User> getUserList() {
        UserMapper mapper = sqlSession.getMapper(UserMapper.class);
        return mapper.getUserList();
    }
}

2.3 测试

public class TestMybatis {
    @Test
    public void testGetUserList() throws Exception{
        ApplicationContext context =new ClassPathXmlApplicationContext("applicationContext.xml");
        UserMapperImpl userMapper = context.getBean("userMapper", UserMapperImpl.class);
        List<User> userList = userMapper.getUserList();
        for (User user:userList
             ) {
            System.out.println(user);
        }
    }
}

2.4 个人理解

​ 通过使用Spring,可以让Mybatis-config.xml配置文件的内容大部分转移到Spring容器中。测试类对数据库进行连接也无需Mybatis工具类,也不用创建对象

  1. 通过Spring容器中dataSource标签获得数据源(Driver,url,username,password)连接指定数据库
  2. 通过Spring容器中sqlSessionFactory绑定mybatis核心配置文件并映射Mapper.xml文件
  3. 通过工厂创建SqlSession对象(SqlSessionTemplate),通过构造器注入传入需要的工厂
  4. 创建实体类实现Mapper接口,设置SqlSessionTemplate成员变量准备注入sqlSession对象,并实现接口的方法
  5. Spring容器中注册实体类,对实体类中的成员变量进行注入,本例中注入准备好的sqlSession对象
  6. 测试类中获得容器中实体类,调用其中的方法

3.第二种方式


<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">
    
		<import resource="applicationContext.xml"/>
    
        <bean id="UserMapperIm" class="com.dao.UserMapperIm">
            <property name="sqlSessionFactory" ref="sqlSessionFactory"/>
        bean>
beans>
public class UserMapperIm extends SqlSessionDaoSupport implements UserMapper{
    public List<User> getUserList() {
        return getSqlSession().getMapper(UserMapper.class).getUserList();
    }
}

总结:实体类继承 SqlSessionDaoSupport,获得getSqlSession方法,在Spring容器中注册实体类注入Factory,相比于第一种少了一个SqlSession

14、声明式事务

​ Spring中的事务管理

  • 声明式事务:AOP
  • 编程式事务:需要在代码中进行实物管理

xmlns:tx="http://www.springframework.org/schema/tx"
xmlns:aop="http://www.springframework.org/schema/aop"

​ 声明事务并与AOP结合

 
    <bean id="transactionManager" class="org.springframework
                                         .jdbc.
                                         datasource.
                                         DataSourceTransactionManager">
        <property name="dataSource" ref="dataSource"/>
    bean>
    
    
    <tx:advice id="txAdvice" transaction-manager="transactionManager">
        
        <tx:attributes>
            <tx:method name="insertUser" propagation="REQUIRED"/>
            <tx:method name="deleteUser" propagation="REQUIRED"/>
        tx:attributes>
    tx:advice>
    <aop:config>
        <aop:pointcut id="txPoint" expression="execution(* dao.*.*(..))"/>
        <aop:advisor advice-ref="txAdvice" pointcut-ref="txPoint"/>
    aop:config>

你可能感兴趣的:(spring,java)