Spring

Spring

项目搭建

1.创建一个maven项目

2.导入Spring依赖

<!-- spring-context -->
        <dependency>
            <groupId>org.springframework</groupId>
            <artifactId>spring-context</artifactId>
            <version>5.2.2.RELEASE</version>
        </dependency>

3.编写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">
    <bean id="user" class="com.ffyc.springdemo.model.User">
        <property name="id" value="1"></property>
        <property name="name" value="张三"></property>
    </bean>
</beans>

4.编写实体类

import lombok.Data;

@Data
public class User {
    private int id;
    private String name;
}

5.测试

public class Test {
  @org.junit.Test
  public void test(){
    ClassPathXmlApplicationContext classPathXmlApplicationContext = new ClassPathXmlApplicationContext("spring.xml");
    User user=classPathXmlApplicationContext.getBean("user",User.class);
    System.out.println(user);
    User user1=classPathXmlApplicationContext.getBean("user",User.class);
    System.out.println(user1);
    System.out.println(user==user1);
  }
}

测试结果

User(id=1, name=张三)
User(id=1, name=张三)
true

Spring Bean 管理

1.基于xml配置管理

2.使用注解标签

@Componment(value=“”)

适用于model类

@Repository(value=“”)

适用于dao层

@Service(value=“”)

适用于service层

@Scope(value=“”)

适用于所有类

@Scope(value=“prototype”) 原型

@Scope(value=“ singleton ”) 单例

@Autowired(value=“”)

用来自动注入对象

注入对象的两种方式:

byName

使用该方法注入对象需要加上@Qualifier(value=“”)标签

byType(默认使用类型查找)

@Resource(name=“”)

由JDK提供的自动注入对象的标签,既可以按照名称匹配Bean,也可以通过名称匹配

默认按照ByName自动注入

注解与XML的对比

注解优点:方便直观高效

注解缺点:修改后需要重新编译代码

XML优点:配置与代码是分离的,修改后无需重新编译,只需要重启服务器

XML缺点:编写麻烦,效率低

项目搭建

编写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"       xmlns:context="http://www.springframework.org/schema/context" xsi:schemaLocation="http://www.springframework.org/schema/beanshttp://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.ffyc.springdemo"></context:component-scan></beans>

编写实体类,dao层,service层,并添加注解标签

@Data
@Component(value = "user")
public class User {
    private int id;
    private String name;
}

@Repository(value = "userDao")
public class UserDao {
   public void save(User user){
       System.out.println("保存管理员"+user);
   }
}
@Service(value = "userService")
public class UserService {
    @Autowired
    UserDao userDao;
   public void save(User user){
       userDao.save(user);
   }
}

测试

public class Test {
    @org.junit.Test
    public void test() {
        ClassPathXmlApplicationContext classPathXmlApplicationContext = new ClassPathXmlApplicationContext("spring.xml");
        User user=classPathXmlApplicationContext.getBean("user",User.class);
        user.setId(1);
        user.setName("张三");
        UserService userService=classPathXmlApplicationContext.getBean("userService",UserService.class);
        userService.save(user);
    }
}

结果:保存管理员User(id=1, name=张三)

Spring JDBC

1.导入JDBC,Mysql,阿里巴巴提供的数据源管理组件

       <!-- spring-jdbc -->
        <dependency>
            <groupId>org.springframework</groupId>
            <artifactId>spring-jdbc</artifactId>
            <version>5.2.2.RELEASE</version>
        </dependency>
        <!-- 阿里数据源 -->
        <dependency>
            <groupId>com.alibaba</groupId>
            <artifactId>druid</artifactId>
            <version>1.1.10</version>
        </dependency>
        <!--MySQL-->
        <dependency>
            <groupId>mysql</groupId>
            <artifactId>mysql-connector-java</artifactId>
            <version>8.0.16</version>
        </dependency>

2.创建config.properties

classDiverName=com.mysql.cj.jdbc.Driver
url=jdbc:mysql://127.0.0.1:3306/mybatis?serverTimezone=Asia/Shanghai
uname=root
upassword=123

3.创建db.xml,用于配置JDBC(在其中导入config.properties)

<?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 https://www.springframework.org/schema/context/spring-context.xsd">
   <!--用来配置数据库相关的东西-->
    <!--导入属性文件-->
    <context:property-placeholder location="config.properties"/>
    <!--管理数据源对象-->
    <bean id="dataSource" class="com.alibaba.druid.pool.DruidDataSource">
        <property name="driverClassName" value="${classDiverName}"></property>
        <property name="url" value="${url}"></property>
        <property name="username" value="${uname}"></property>
        <property name="password" value="${upassword}"></property>
        <property name="initialSize" value="10"></property>
        <property name="minIdle" value="5"></property>
        <property name="maxActive" value="20"></property>
    </bean>
    <!--在配置文件中创建 JdbcTemplate-->
    <bean id="jdbcTemplate" class="org.springframework.jdbc.core.JdbcTemplate">
        <property name="dataSource" ref="dataSource"></property>
    </bean>

</beans>

4.在spring.xml中导入db.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: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 https://www.springframework.org/schema/context/spring-context.xsd">
    <context:component-scan base-package="com.ffyc.springdemo"></context:component-scan>

    <import resource="classpath:db.xml"></import>
</beans>

5.测试

@Service(value = "userService")
public class UserService {
    /*@Autowired
    UserDao userDao;*/
    @Autowired
    JdbcTemplate jdbcTemplate;

    public void save() {
//       jdbcTemplate.update("delete from user where id=?",1);
        List<User> users=jdbcTemplate.query("select * from user", new RowMapper<User>() {
            @Override
            public User mapRow(ResultSet resultSet, int i) throws SQLException {
                User user = new User();
                user.setId(resultSet.getInt("id"));
                user.setName(resultSet.getNString("name"));
                return user;
            }
        });
        System.out.println(users);
    }
}
public class Test2 {
    @Autowired
    JdbcTemplate jdbcTemplate;
    @Test
    public void Test(){
        ClassPathXmlApplicationContext classPathXmlApplicationContext = new ClassPathXmlApplicationContext("spring.xml");
        UserService userService=classPathXmlApplicationContext.getBean("userService",UserService.class);
        userService.save();
    }
}
结果
五月 27, 2023 3:51:49 下午 com.alibaba.druid.support.logging.JakartaCommonsLoggingImpl info
信息: {dataSource-1} inited
[User(id=3, name=张三), User(id=4, name=李四), User(id=5, name=小王)]
补充

JdbcTemplate 中常用的方法

execute:无返回值,可执行 ddl,增删改语句

update:执行新增、修改、删除语句;

queryForXXX:执行查询相关语句;

AOP

简介

是一种编程技巧,将程序中的非业务代码进行提取,在不改动原代码的基础上为程序添加额外的功能。使用该技巧可以将业务代码和非业务代码进行隔离,使得各个部分的耦合度降低。

非业务代码:验证,日志,提交事务,统一异常处理等。

底层实现:使用的是动态代理模式

AOP中的基本概念

连接点:可以被增强的方法

切入点:实际被增强的方法

通知:需要增强的功能,有五个通知(前置通知,后置通知,环绕通知,最终通知,异常通知)

切面:将通知添加到切入点的过程叫切面

目标:代理的目标对象

代理:向目标对象通知时创建的代理对象

Spring AOP的实现

使用配置实现
1.下载AOP相关jar
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-aspects</artifactId>
<version>5.2.2.RELEASE</version>
</dependency>
2.使用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: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 https://www.springframework.org/schema/context/spring-context.xsd http://www.springframework.org/schema/aop https://www.springframework.org/schema/aop/spring-aop.xsd">

    <!--将通知交给spring管理-->
    <bean id="myUtil" class="com.ffyc.springdemo.utils.MyUtil" ></bean>

    <aop:config>
        <!-- 配置切入点 -->
       <aop:pointcut id="save" expression="execution(* com.ffyc.springdemo.dao.UserDao.save(..))"/>
        <!--配置通知-->
        <aop:aspect ref="myUtil">
            <aop:before method="writeLog" pointcut-ref="save"></aop:before>
            <!--<aop:after method="commit" pointcut-ref="save"></aop:after>-->
            <aop:after-returning method="commit" pointcut-ref="save"></aop:after-returning>
            <aop:after-throwing method="exception" throwing="e" pointcut-ref="save"></aop:after-throwing>
        </aop:aspect>
    </aop:config>
</beans>
3.util类
public class MyUtil {
    public void writeLog(){
        System.out.println("打印日志");
    }
    public void commit(){
        System.out.println("提交事务");
    }
    public void exception(Exception e){
        System.out.println("异常处理"+e);
    }
}
4.UserDao
@Repository(value = "userDao")
public class UserDao {
  //被增强的方法
   public void save(){
       System.out.println("保存管理员");
       System.out.println(10/0);
   }
}
5.测试
打印日志
保存管理员
异常处理java.lang.ArithmeticException: / by zero

如果是使用最终通知,最终结果为:

打印日志
保存管理员
提交事务
异常处理java.lang.ArithmeticException: / by zero

最终通知无论是否出现异常都会执行

环绕通知

util类

public void aroundAdvice(ProceedingJoinPoint point){
        try {
            System.out.println("前置通知");
            //调用业务方法
            point.proceed();
            System.out.println("后置通知");
        } catch (Throwable throwable) {
            System.out.println("异常通知"+throwable.getMessage());
            throwable.printStackTrace();
        }
        System.out.println("最终通知");
    }

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

    <!--将通知交给spring管理-->
    <bean id="myUtil" class="com.ffyc.springdemo.utils.MyUtil" ></bean>

    <aop:config>
        <!-- 配置切入点 -->
       <aop:pointcut id="save" expression="execution(* com.ffyc.springdemo.dao.UserDao.save(..))"/>
        <!--配置通知-->
        <aop:aspect ref="myUtil">
            <!--<aop:before method="writeLog" pointcut-ref="save"></aop:before>
            <aop:after method="commit" pointcut-ref="save"></aop:after>-->
            <!--<aop:after-returning method="commit" pointcut-ref="save"></aop:after-returning>-->
            <!--<aop:after-throwing method="exception" throwing="e" pointcut-ref="save"></aop:after-throwing>-->
            <aop:around method="aroundAdvice" pointcut-ref="save"></aop:around>
        </aop:aspect>
    </aop:config>
</beans>

测试结果

前置通知
保存管理员
后置通知
最终通知
使用注解方式实现
在spring.xml中添加配置
<aop:aspectj-autoproxy />
在通知上加上标签注解
@Component //让spring管理生成对象
@Aspect //表明是含有通知的类
public class MyUtil {
    @Before("execution(* com.ffyc.springdemo.dao.UserDao.save(..))")
    public void writeLog(){
        System.out.println("打印日志");
    }
    @AfterReturning("execution(* com.ffyc.springdemo.dao.UserDao.save(..))")
    public void commit(){
        System.out.println("提交事务");
    }
    @AfterThrowing(value = "execution(* com.ffyc.springdemo.dao.UserDao.save(..))",throwing = "e")
    public void exception(Exception e){
        System.out.println("异常处理"+e.getMessage());
    }
    @Around("execution(* com.ffyc.springdemo.dao.UserDao.save(..))")
    public void aroundAdvice(ProceedingJoinPoint point){
        try {
            System.out.println("前置通知");
            //调用业务方法
            point.proceed();
            System.out.println("后置通知");
        } catch (Throwable throwable) {
            System.out.println("异常通知"+throwable.getMessage());
            throwable.printStackTrace();
        }
        System.out.println("最终通知");
    }
}

Spring事务

事务可以看成是数据库若干操作组成的一个单元。

由于在数据库操作时,是由多步操作组成的,任何一步都有可能发生异常,并且导致后面的操作无法正确进行,这种情况下需要回退。数据库事务就是为了保证用户的每一步操作都是可靠的,并且每一步都必须正常执行,只要发生异常就会回退到数据库事务还未开始的状态,从而保证数据满足一致性的要求。

编程时事务

需要注入一个事务管理对象TransactionTemplate ,然后在我们代码中需要提交事务或回滚事务时自己写代 码实现.

声明式事务

使用xml
使用注解标签
1.配置事物管理器
<!-- 配置 spring 事务管理类, 并注入数据源 --> 

<bean id="transactionManager" 

class="org.springframework.jdbc.datasource.DataSourceTransactionManager"> 

<property name="dataSource" ref="dataSource"></property> 

</bean>
2.注解方式
<!-- 开启注解事务管理 --> 

<tx:annotation-driven transaction-manager="transactionManager"/>
3.在方法上添加@Transactional标签
 @Transactional
    public void saveAdmin(){
        jdbcTemplate.update("update  user set name =? where id=?","猪猪侠",3);
        int i=10/0;
        jdbcTemplate.update("update  user set name =? where id=?","喜羊羊",4);
    }

解释:开启事务后,中间出现异常,不会提交数据,所以id为3的数据也不会被修改

@Transactional

用于service层,一个事务逻辑方法中可能会调用多个dao中的方法,有多条sql,所以需要放在同一个事物中。

用法

用于类上,所有方法都会被添加事务管理

用于方法上,方法会在事务管理中进行

不生效情况
1.应用在非public方法上
2.异常被捕获
3.出现编译期异常

默认只对运行期异常进行回滚,可以设置@Transactional(rollbackFor = Exception.class)

4.事物传播行为设置错误
5.数据库殷勤不支持事务(innodb支持事务,myisam不支持事务)
6.同一个类中,使用非代理对象调用一个有事务的方法,导致事务出错

事务传播行为

概念

是spring提供的一个额外的功能,不属于数据库的功能,指的是一个事务方法调用另一个类中的事务方法。

七种事务传播行为(其中4种)

PROPAGATION_REQUIRED(默认)

没有事务就会新建,有事务就会加入

PROPAGATION_SUPPORTS

有事务就加入,没有就按照没有事务的方法进行

PROPAGATION_NEVER

以非事务的方法进行,有事务就会抛出异常

PROPAGATION_REQUIRES_NEW

无论有没有事务,都会新建一个新的事务

Spring中集成Mybatis

1.导入Spring Mabatis结合的jar包

<dependency>
<groupId>org.mybatis</groupId>
<artifactId>mybatis-spring</artifactId>
<version>1.3.1</version>
</dependency>

2.配置 sqlSessionFactory

<bean id="sqlSessionFactory" class="org.mybatis.spring.SqlSessionFactoryBean">
<property name="dataSource" ref="dataSource"></property>
<property name="configLocation" value="mybatis-config.xml"></property>
<property name="mapperLocations" value="com/ff/*Mapper.xml">
</property>
</bean>

3.指定生成接口代理

<bean id="mapperFactory" class="org.mybatis.spring.mapper.MapperScannerConfigurer">
<property name="basePackage" value="com.ff.ssm.dao"></property>
<property name="sqlSessionFactoryBeanName" value="sqlSessionFactory">
</property>
</bean>
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值