spring学习笔记

学习笔记 专栏收录该内容
5 篇文章 0 订阅

Spring

简介

导包

<!--spring mvc-->
<!--会自动下载一些jar包-->
<dependency>
    <groupId>org.springframework</groupId>
    <artifactId>spring-webmvc</artifactId>
    <version>5.2.9.RELEASE</version>
</dependency>
<!--jdbc mybatis整合-->
<dependency>
    <groupId>org.springframework</groupId>
    <artifactId>spring-jdbc</artifactId>
    <version>5.2.9.RELEASE</version>
</dependency>


控制反转(IOC) 面向切面编程(AOP)

IOC控制反转

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

IOC实现:

  • 注解

  • xml

通过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="..." class="...">  
    <!-- collaborators and configuration for this bean go here -->
  </bean>

  <bean id="..." class="...">
    <!-- collaborators and configuration for this bean go here -->
  </bean>
  <!-- more bean definitions go here -->
</beans>

获取对象:

ApplicationContext context = new ClassPathXmlApplicationContext("beans.xml");//可多个.xml
Dao mysql = context.getBean("mysql", Dao.class);

IOC创建对象Bean的方式

Bean在被注册到容器的时候被实例化了

多次取 取得的是同一个

  1. 使用无参构造创建对象 【默认】

    User user = context.getBean("user");
    
  2. 构造器创建对象

    <!--下标-->
    <bean id="exampleBean" class="examples.ExampleBean">
      <constructor-arg index="0" value="7500000"/>
      <constructor-arg index="1" value="42"/>
    </bean>
    
    <!--类型-->
    <bean id="exampleBean" class="examples.ExampleBean">
      <constructor-arg type="int" value="7500000"/>
      <constructor-arg type="java.lang.String" value="42"/>
    </bean
    
    <!--直接通过参数名-->
    <beans>
      <bean id="beanOne" class="x.y.ThingOne">
        <constructor-arg ref="beanTwo"/>
        <constructor-arg ref="beanThree"/>
        <constructor-arg name="" value=""/>
      </bean>
    
      <bean id="beanTwo" class="x.y.ThingTwo"/>
    
      <bean id="beanThree" class="x.y.ThingThree"/>
    </beans>
    

Spring配置

别名

可以在上使用别名

配置

可以在上使用别名

import

将多个配置文件导入

DI依赖注入

  • 构造器注入
  • set注入
  • 拓展注入

set注入

依赖注入本质 set注入

  • 依赖:bean对象的创建依赖于容器
  • 注入:bean中的属性 由容器来注入

类型:

bean | ref | idref | list | set | map | props | value | null

依赖注入例子:

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

<bean class="com.ws.pojo.Student" id="student">
  <!--       string-->
  <property name="name" value="王顺"/>
  <!--       bean-->
  <property name="address" ref="address"/>
  <!--       数组-->
  <property name="books">
    <array>
      <value>book1</value>
      <value>book2</value>
    </array>
  </property>
  <!--       list-->
  <property name="hobbies">
    <array>
      <value>篮球</value>
      <value>足球</value>
    </array>
  </property>
  <!--        map-->
  <property name="card">
    <map>
      <entry key="baba" value="lala"/>
      <entry key="wowo" value="haha"/>
    </map>
  </property>
  <!--       set-->
  <property name="games">
    <set>
      <value>lol</value>
      <value>csgo</value>
    </set>
  </property>
  <!--       properties-->
  <property name="info">
    <props>
      <prop key="user">root</prop>
      <prop key="password">root</prop>
    </props>
  </property>
  <!--       null-->
  <property name="wife">
    <null/>
  </property>
</bean>

<bean class="com.ws.pojo.Address" id="address">
  <property name="address" value="北碚"/>
</bean>

拓展注入

  • p命名空间【约等于 property】
  • c命名空间 【约等于 constructor】

Bean的作用域

单例【默认】 所有共享一个对象

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

原型 每次get的是新对象

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

Bean的自动装配

自动给Bean设置属性

三种装配方式

  1. 再xml显示配置
  2. 在java显示配置
  3. 隐式 自动装配Bean

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

使用xml进行自动装配

<bean id="person" class="com.ws.pojo.Person" autowire="byName"/>
<!-- autowire 使用byName | byType-->
<bean id="cat" class="com.ws.pojo.Cat"/>

<bean id="dog" class="com.ws.pojo.Dog"/>

<!--byName: 在容器中上下文找和自己对象set方法后面的值对于的bean id-->
<!--byName: 在容器中上下文找和自己对象属性类型相同的bean-->

注解实现自动装配

使用注解:

  1. 导入约束

  2. 配置注解的支持(context)

    <?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 才用的是ByType的方式进行注入

bean需放在IOC容器中

当IOC中间有多个相同类型的Bean时使用

@Qualifier(value=“xxx”)

(使用java的 @Resource)也可以实现注入

  • @Autowired 先ByType 再ByName
  • @Resource 先ByName再ByType

Spring 注解开发

在.xml文件中添加

扫描文件下的注解

<context:component-scan base-package="com.ws.pojo"/>

@Component

等于在xml文件中写

<bean id="" class=""/>

将Bean 放在容器中

名字为类的小写

@Value(“ ”)

给属性注入值

@Component的衍生注解

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

三个功能相同

@Scope(“ ”)

作用域

使用java的方式配置spring

不使用Spring的xml

@Configuration

本身是个@Component

@Configuration
@ComponentScan("com.ws")
public class MyConfig {

	@Bean
	public Person getPerson(){
		return new Person();
	}

	@Bean
	public Dog getDog(){
		return  new Dog();
	}

	@Bean
	public Cat getCat(){
		return new Cat();
	}
}

测试:

@Test
public  void  test(){
  ApplicationContext context = new AnnotationConfigApplicationContext(MyConfig.class);
  Person person = context.getBean("getPerson", Person.class);
  person.getCat().shut();
}

context.getBean(获取方法的名字)

代理模式

  • 静态代理
  • 动态代理

静态代理

动态代理

  • 基于接口—JDK 【ProxyIvocationHandler
  • 基于类—cglib
  • java 字节码javassist

jdk:

Proxy 生成动态代理实例

InvocationHandler 调用处理程序 并 返回结果

  • 写接口

    public interface Subject {
      public void sayHello(String msg);
    }
    
  • 接口的实现

    public class SubjectImpl implements Subject {
    	@Override
    	public void sayHello(String msg) {
    		System.out.println("hello " + msg);
    	}
    }
    
  • InvokeHandler

    public class SubjectInvoke implements InvocationHandler {
    	Subject subject;
    
    	public SubjectInvoke(Subject subject) {
    		this.subject = subject;
    	}
    
    	public void setSubject(Subject subject) {
    		this.subject = subject;
    	}
    
    	@Override
    	public Object invoke(Object proxy, Method method, Object[] args) throws Throwable {
    		System.out.println("--- before ---");
    		Object invoke = method.invoke(subject, args);
    		System.out.println("--- after ---");
    		return invoke;
    	}
    }
    
  • 测试

    @Test
    public void test(){
      Subject subject = new SubjectImpl();
      InvocationHandler subjectInvoke = new SubjectInvoke(subject);
      
      Subject o = (Subject) Proxy.newProxyInstance(
        this.getClass().getClassLoader(), 				
        subject.getClass().getInterfaces(),
        subjectInvoke);
      
      o.sayHello("wang!");
    
    
  • [外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-5AoNjg0L-1603700470096)(C:\Users\ws666\AppData\Roaming\Typora\typora-user-images\image-20201019210809453.png)]

AOP

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

方式一 使用API

service:


public class UserServiceImpl  implements UserService{
  @Override
  public void add() {
  	System.out.println("增添了一个方法");
  }

  @Override
  public void del() {
  	System.out.println("删除了一个方法");
  }

  @Override
  public void update() {
  	System.out.println("更新了一个方法");
  }

  @Override
  public void find() {
  	System.out.println("查找了一个方法");
  }
}

需要增加的功能:

执行后需要继承的接口:

public class AfterLog implements AfterReturningAdvice {
	@Override
	public void afterReturning(Object o, Method method, Object[] objects, Object target) throws Throwable {
		System.out.println(target.getClass().getName() + " 的 " +method.getName() + "被执行了 ");
	}
}

执行前需要继承的接口:

public class BeforeLog implements MethodBeforeAdvice {

	//target:目标对象
	//method:要执行目标对象的方法
	@Override
	public void before(Method method, Object[] objects, Object target) throws Throwable {
		System.out.println(target.getClass().getName() + " 的 " +method.getName() + "被执行了 ");
	}
}

配置文件:

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

  <bean id="userServiceImpl" class="com.ws.service.UserServiceImpl"/>
  <bean id="afterLog" class="com.ws.log.AfterLog"/>
  <bean id="beforeLog" class="com.ws.log.BeforeLog"/>

  <aop:config>
    <!--切入点-->
    <aop:pointcut id="pointcut" expression="execution(* com.ws.service.UserServiceImpl.*(..))"/>

    <aop:advisor advice-ref="afterLog" pointcut-ref="pointcut"/>
    <aop:advisor advice-ref="beforeLog" pointcut-ref="pointcut"/>
    
  </aop:config>

</beans>

方式二 自定义类

DiyLog类:

public class DiyLog {

	public void before(){
		System.out.println("===before===");
	}

	public void after(){
		System.out.println("===after===");
	}
}

Application.xml

<!--    方式二:自定义类-->
    <bean class="com.ws.log.DiyLog" id="diyLog"/>
    <aop:config>
        <aop:aspect ref="diyLog">
            <aop:pointcut id="pointcut" expression="execution(* com.ws.service.UserServiceImpl.*(..))"/>

            <aop:before method="before" pointcut-ref="pointcut"/>
            <aop:after method="after" pointcut-ref="pointcut"/>
        </aop:aspect>
    </aop:config>

缺陷:不能与类进行相关的操作

方式三 使用注解

@Aspect
@Component
public class AnnotationLog {

	@Before("execution(* com.ws.service.UserServiceImpl.*(..))")
	public void before(){
		System.out.println("before");
	}

	@After("execution(* com.ws.service.UserServiceImpl.*(..))")
	public  void  after(){
		System.out.println("after");
	}

	@Around("execution(* com.ws.service.UserServiceImpl.*(..))")
	public void around(ProceedingJoinPoint joinPoint) throws Throwable {
		System.out.println("环绕前");
    //执行方法
		Object proceed = joinPoint.proceed();
		System.out.println("环绕后");
	}
}

在xml中加入:

<!--进行扫描--> 
<aop:aspectj-autoproxy/>

整合Mybatis

方式一

spring-dao.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:aop="http://www.springframework.org/schema/aop"
       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/aop
                           https://www.springframework.org/schema/aop/spring-aop.xsd http://www.springframework.org/schema/context https://www.springframework.org/schema/context/spring-context.xsd">


    <bean id="sqlSessionFactory" class="org.mybatis.spring.SqlSessionFactoryBean">
        <property name="dataSource" ref="dataSource"/>
<!-- 连接mybatis的文件-->
        <property name="configLocation" value="classpath:myBatis-config.xml"/>
<!-- 连接mapper可在mybatis的配置文件中写-->
        <property name="mapperLocations" value="classpath:com/ws/mapper/*.xml"/>
    </bean>


    <bean id="sqlSession" class="org.mybatis.spring.SqlSessionTemplate">

        <constructor-arg index="0" ref="sqlSessionFactory"/>
    </bean>




    <bean id="dataSource" class="org.springframework.jdbc.datasource.DriverManagerDataSource">
        <property name="driverClassName" value="com.mysql.cj.jdbc.Driver"/>
        <property name="url" value="jdbc:mysql://localhost:3306/mybatis?useSSL=true&amp;useUnicode=true&amp;characterEncoding=UTF-8&amp;serverTimezone=UTC"/>
        <property name="username" value="root"/>
        <property name="password" value="root"/>
    </bean>



</beans>

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"
       xmlns:aop="http://www.springframework.org/schema/aop"
       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/aop
                           https://www.springframework.org/schema/aop/spring-aop.xsd http://www.springframework.org/schema/context https://www.springframework.org/schema/context/spring-context.xsd">

    <import resource="spring-dao.xml"/>
    <bean id="userMapper" class="com.ws.mapper.UserMapperImpl">
        <property name="sqlSession" ref="sqlSession"/>
    </bean>

</beans>

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>

    <typeAliases>
        <package name="com.ws.pojo"/>
        <package name="com.ws.mapper"/>
    </typeAliases>

</configuration>

UserMapperImpl:

package com.ws.mapper;

import com.ws.pojo.User;
import org.mybatis.spring.SqlSessionTemplate;

import java.util.List;

public class UserMapperImpl implements UserMapper{

	SqlSessionTemplate sqlSession;

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

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

思路!:

  • spring-dao.xml 用于链接数据库和代替MybatisUtil工具类
    • 写dataSource链接数据库
    • 创建SqlSessionFactory
      • 链接dataSource
      • 链接mybatis的配置xml
      • 选择mapper【可以在mybatis的配置文件中写】
    • 用创建的sqlSessionFactory生成sqlSessionTemplate【相当于sqlSession】
      • 将sqlSessionTemplate中的属性sqlSessionFactory赋值
  • 在applicationContext.xml文件导入整合mybatis的spring-dao.xml
  • 使用MapperImpl 添加属性sqlSession【相当于service层】

方式二

Impl文件:

public class UserMapperImpl2 extends SqlSessionDaoSupport implements UserMapper{

	@Override
	public List<User> getAllUser() {
		return getSqlSession().getMapper(UserMapper.class).getAllUser();
	}
}

继承SqlSessionDaoSupport 就不用再配置文件中生成SqlSessionTemplate

<bean id="userMapper2" class="com.ws.mapper.UserMapperImpl2">
    <property name="sqlSessionFactory" ref="sqlSessionFactory"/>
</bean>

为其父类添加生成的sqlSessionFactory

声明式事务

事务:要么都成功 要么都失败

事务ACID原则

  • 原子性
  • 隔离性
  • 持久性
  • 一致性

在spring的配置文件中添加:

xmlns:tx="http://www.springframework.org/schema/tx"
xsi:schemaLocation="
http://www.springframework.org/schema/tx
https://www.springframework.org/schema/tx/spring-tx.xsd">

使用aop声明事务

<bean id="dataSource" class="org.springframework.jdbc.datasource.DriverManagerDataSource">
        <property name="driverClassName" value="com.mysql.cj.jdbc.Driver"/>
        <property name="url" value="jdbc:mysql://localhost:3306/mybatis?useSSL=true&amp;useUnicode=true&amp;characterEncoding=UTF-8&amp;serverTimezone=UTC"/>
        <property name="username" value="root"/>
        <property name="password" value="root"/>
    </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/ws/mapper/*.xml"/>
    </bean>

    <bean id="transactionManager" class="org.springframework.jdbc.datasource.DataSourceTransactionManager">
        <property name="dataSource" ref="dataSource"/>
    </bean>

    <tx:advice id="ttt" transaction-manager="transactionManager">
        <tx:attributes >
            <tx:method name="add" propagation="REQUIRED"/>
            <tx:method name="delete" propagation="REQUIRED"/>
            <tx:method name="selectAll" propagation="REQUIRED"/>
        </tx:attributes>
    </tx:advice>

    <aop:config>
        <aop:pointcut id="txPointcut" expression="execution(* com.ws.mapper.*.*(..))"/>
        <aop:advisor advice-ref="ttt" pointcut-ref="txPointcut"/>
    </aop:config>
  • 在容器中注册事务管理【transaction-manager】

    <bean id="transactionManager" class="org.springframework.jdbc.datasource.DataSourceTransactionManager">
      <property name="dataSource" ref="dataSource"/>
    </bean>
    
  • 某些方法中添加事务

    <tx:advice id="ttt" transaction-manager="transactionManager">
      <tx:attributes >
        <tx:method name="add" propagation="REQUIRED"/>
        <tx:method name="delete" propagation="REQUIRED"/>
        <tx:method name="selectAll" propagation="REQUIRED"/>
      </tx:attributes>
    </tx:advice>
    
  • 使用aop 切入事务

    <aop:config>
      <aop:pointcut id="txPointcut" expression="execution(* com.ws.mapper.*.*(..))"/>
      <aop:advisor advice-ref="ttt" pointcut-ref="txPointcut"/>
    </aop:config>
    

    <aop:pointcut id=“txPointcut” expression=“execution(* com.ws.mapper..(…))”/>
    <aop:advisor advice-ref=“ttt” pointcut-ref=“txPointcut”/>
    </aop:config>




- 在容器中注册事务管理【transaction-manager】

  ```xml
  <bean id="transactionManager" class="org.springframework.jdbc.datasource.DataSourceTransactionManager">
    <property name="dataSource" ref="dataSource"/>
  </bean>
  • 某些方法中添加事务

    <tx:advice id="ttt" transaction-manager="transactionManager">
      <tx:attributes >
        <tx:method name="add" propagation="REQUIRED"/>
        <tx:method name="delete" propagation="REQUIRED"/>
        <tx:method name="selectAll" propagation="REQUIRED"/>
      </tx:attributes>
    </tx:advice>
    
  • 使用aop 切入事务

    <aop:config>
      <aop:pointcut id="txPointcut" expression="execution(* com.ws.mapper.*.*(..))"/>
      <aop:advisor advice-ref="ttt" pointcut-ref="txPointcut"/>
    </aop:config>
    
  • 0
    点赞
  • 0
    评论
  • 0
    收藏
  • 打赏
    打赏
  • 扫一扫,分享海报

©️2022 CSDN 皮肤主题:深蓝海洋 设计师:CSDN官方博客 返回首页

打赏作者

悟世皆为空!

你的鼓励将是我创作的最大动力

¥2 ¥4 ¥6 ¥10 ¥20
输入1-500的整数
余额支付 (余额:-- )
扫码支付
扫码支付:¥2
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值