首页 > 其他分享 >Spring框架

Spring框架

时间:2023-02-25 18:13:44浏览次数:52  
标签:框架 Spring class Bean 注解 public 注入

目录

Spring框架

一、Spring初体验

1.1 Spring简介

认识Spring:

image-20230202144231764

image-20230202144253027

Spring提供一站式解决方法,对开发的各层都有提供支持。

image-20230222141943468

Spring 体系结构:

Spring 由 20 多个模块组成,它们可以分为数据访问/集成(Data Access/Integration)、 Web、面向切面编程(AOP, Aspects)、提供JVM的代理 (Instrumentation)、消息发送(Messaging)、 核心容器(Core Container)和测试(Test)。

image-20230202141831299

Spring特性:

  • 非侵入式:基于Spring开发的应用中的对象可以不依赖于Spring的API。
class HelloServlet extends HttpServlet{   // 处理请求的类:侵入式设计; servlet侵入
    
}
class HelloHandler {    // 处理请求的类: 非侵入式设计
    
}
  • 容器:Spring是一个容器,因为它包含并且管理应用对象的生命周期。
  • 组件化:Spring实现了使用简单的组件配置组合成一个复杂的应用。在 Spring 中可以使用XML和Java注解组合这些对象。
  • 一站式:在IOC和AOP的基础上可以整合各种企业应用的开源框架和优秀的第三方类库(实际上Spring 自身也提供了表述层的SpringMVC和持久层的JDBCTemplate)。

IOC 容器:

image-20230222204231021

Spring 通过 IoC 容器来管理所有 Java 对象的实例化和初始化,控制对象与对象之间的依赖关系。我们将由 IoC 容器管理的 Java 对象称为 Spring Bean,它与使用关键字 new 创建的 Java 对象没有任何区别。

Inversion of control  控制反转容器
之前:我们用对象,自己new
现在:我们用对象,去ioc容器中获取,对象怎么创建的不用管,只要去用就行了。
IOC 作用: 帮助我们创建对象、管理对象的生命周期。
          User user = new user()   创建对象
DI dependency injection 依赖注入          
class UserService {
     private UserDao userDao
     public void setUserDao(UserDao userDao){
          this.userDao = userDao;
     }
     public void save(){
         userdao.saveUser();
     }
}
UserSevice us = new UserService();  // IOC: 创建对象
us.setUserDao(userDao);             // IOC:  管理对象的依赖关系,DI,依赖注入
us.save();  // 报错

1.2 入门案例

  • 导入jar包
  <dependencies>
        <!-- https://mvnrepository.com/artifact/org.springframework/spring-context -->
        <dependency>
            <groupId>org.springframework</groupId>
            <artifactId>spring-context</artifactId>
            <version>5.2.12.RELEASE</version>
        </dependency>
    </dependencies>
  • 编写核心配置文件

    • 配置文件路径:src/main/resources

    • 示例代码

<?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 对象的名称,从容器中获取对象可以通过id
            class 对象的全路径
            scope 对象的范围
                singlton 默认;单例的对象;创建容器的时候自动创建
                prototype 多例; 每次从容器中获取对象都创建全新的对象
            lazy-init="true" 单例的对象默认在创建容器时候创建;
                             lazy-init设置为true表示第一次使用时候才创建
    -->
    <bean id="user" class="com.wnxy.entity.User" lazy-init="true" scope="singleton">
        <property name="id" value="100"/>
        <!-- public void setName(String name) {-->
        <property name="name" value="Jacky"/>
    </bean>
</beans>
  • 创建容器测试
public class App1 {
    public static void main(String[] args) {
        // 创建IOC容器 = ApplicationContext + bean.xml
        // 默认就会创建单例对象
        ApplicationContext ac =
                new ClassPathXmlApplicationContext("bean.xml");
        // 从容器中获取对象
        User user1 = (User) ac.getBean("user");
        User user2 = (User) ac.getBean("user");
        System.out.println(user1 == user2);
    }
}

1.3 Spring中getBean()三种方式

  • getBean(String beanId):通过beanId获取对象

    • 不足:需要强制类型转换,不灵活
  • getBean(Class clazz):通过Class方式获取对象

    • 不足:容器中有多个相同类型bean的时候,会报如下错误:

      expected single matching bean but found 2: stuZhenzhong,stuZhouxu

  • getBean(String beanId,Clazz clazz):通过beanId和Class获取对象

    • 推荐使用

注意:框架默认都是通过无参构造器,帮助我们创建对象。

所以:如提供对象的构造器时,一定添加无参构造器

1.4 bean标签的属性

  • bean标签
    • id:bean的唯一标识
    • class:定义bean的类型【class全类名】
  • 子标签
    • property:为对象中属性赋值【set注入】
      • name属性:设置属性名称
      • value属性:设置属性数值

1.5 BeanFactory与ApplicationContext

概述

Spring 框架带有两个 IOC 容器—— BeanFactoryApplicationContextBeanFactory是 IOC 容器的最基本版本,ApplicationContext扩展了BeanFactory的特性。

类结构

image-20230202151859544

类关系

image-20230202152438004

  • BeanFactory接口:是Spring bean容器的根接口,提供获取bean,是否包含bean,是否单例与原型,获取bean类型,bean 别名的方法 。它最主要的方法就是getBean(String beanName)。

  • BeanFactory的三个核心子接口:

    HierarchicalBeanFactory:提供父容器的访问功能
    ListableBeanFactory:提供了批量获取Bean的方法
    AutowireCapableBeanFactory:在BeanFactory基础上实现对已存在实例的管理

BeanFactory源码

public interface BeanFactory {
    /**
     * 用来引用一个实例,或把它和工厂产生的Bean区分开,就是说,如果一个FactoryBean的名字为a,那么,&a会得到那个Factory
     */
    String FACTORY_BEAN_PREFIX = "&";
    /*
     * 四个不同形式的getBean方法,获取实例
     */
    Object getBean(String name) throws BeansException;
    <T> T getBean(String name, Class<T> requiredType) throws BeansException;
    <T> T getBean(Class<T> requiredType) throws BeansException;
    Object getBean(String name, Object... args) throws BeansException;
     // 根据名称判断bean是否存在
    boolean containsBean(String name);
    // 是否为单实例Bean
    boolean isSingleton(String name) throws NoSuchBeanDefinitionException;
    // 是否为原型(多实例)
    boolean isPrototype(String name) throws NoSuchBeanDefinitionException;
    // 名称、类型是否匹配
    boolean isTypeMatch(String name, Class<?> targetType)
            throws NoSuchBeanDefinitionException;
    // 获取类型
    Class<?> getType(String name) throws NoSuchBeanDefinitionException;
    // 根据实例的名字获取实例的别名
    String[] getAliases(String name);
}

延迟加载与立即加载

BeanFactory按需加载 bean,而ApplicationContext在启动时加载所有 bean。

@Test
public void test2() {
    Resource res = new ClassPathResource("beans.xml");
    BeanFactory factory = new XmlBeanFactory(res);
    //只有当我们显式调用getBean()方法时,BeanFactory中定义的 bean才会被加载
    factory.getBean("juice");
}

ApplicationContext以更加面向框架的风格增强了BeanFactory,并提供了一些适用于企业应用程序的特性。

  • 默认初始化所有的Singleton,也可以通过配置取消预初始化。
  • 继承MessageSource,因此支持国际化。
  • 资源访问,比如访问URL和文件。
  • 事件传播特性,即支持aop特性。
  • 同时加载多个配置文件。
  • 以声明式方式启动并创建Spring容器。

ApplicationContext:是IOC容器另一个重要接口, 它继承了BeanFactory的基本功能, 同时也继承了容器的高级功能,如:MessageSource(国际化资源接口)、ResourceLoader(资源加载接口)、ApplicationEventPublisher(应用事件发布接口)等。

二、Spring依赖注入

2.1 set 方法注入

(1)、实体类

User

(2)、bean2.xml

<bean id=user class="User">
   <property name="User对象的属性" value="属性值"/>
</bean>

(3)、测试- junit 测试用例

第一:

<!--添加junit单元测试依赖包-->
<dependency>
    <groupId>junit</groupId>
    <artifactId>junit</artifactId>
    <version>4.12</version>
    <!--test 表示当前jar包只在测试中有效,不会打入war包中。实际运行无效。-->
    <scope>test</scope>
</dependency>

第二:使用@Test注解、@Before

2.2 构造器注入

constructor-arg 用户构造器参数:

<?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">
    <!-- 构造器注入-->
    <!--
        constructor-arg 构造器注入
            value 直接给定参数值
            ref   参数值引用的是容器中的另外一个对象
            index 第几个参数,从0开始
            type  参数类型
            name  参数名称
    -->
    <bean id="house" class="com.wnxy.entity.House">
        <constructor-arg value="100" index="0"/>
        <constructor-arg index="1" ref="str"/>
    </bean>
    <!--创建一个字符串,值是:1栋101房-->
    <!--String str = new String("1栋101房"); -->
    <bean id="str" class="java.lang.String">
        <constructor-arg value="1栋101房"/>
    </bean>
</beans>

2.3 p名称空间注入

注意:需要导入p名称空间

<?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:p="http://www.springframework.org/schema/p"
       xsi:schemaLocation="http://www.springframework.org/schema/beans
       http://www.springframework.org/schema/beans/spring-beans.xsd">
     <!--p名称空间注入,简化property注入,也是set方法注入-->
    <bean id="house" class="com.wnxy.entity.House" p:id="100" p:houseNo="1栋101房"></bean>
</beans>

2.4 对象注入

对象准备:

public class UserDao {
    public void save(){
        System.out.println("dao.save()");
    }
}

public class UserService {
    private UserDao userDao;
    public void setUserDao(UserDao userDao) {
        this.userDao = userDao;
    }
    public void save(){
        userDao.save();
    }
}

配置:

<?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">
    <!--先创建dao-->
    <bean id="userDao" class="com.wnxy.spring.dao.UserDao"></bean>
    <!--再创建service,注入dao-->
    <bean id="userService1" class="com.wnxy.spring.service.UserService">
        <!-- ref 表示引用容器中的另外一个bean
        <property name="userDao" ref="userDao"/>
        -->
        <!--通过SpEL(SpringExpressionLanguage SpEL)表达式引用容器中的对象:value=#{beanId}-->
        <property name="userDao" value="#{userDao}"/>
    </bean>
        
    <!--内部bean写法-->
    <bean id="userService" class="com.wnxy.spring.service.UserService">
        <property name="userDao">
            <bean class="com.wnxy.spring.dao.UserDao"/>
        </property>
    </bean>
</beans>

2.5 集合注入

对象准备:

public class UserService {
    // 注入集合数据
    private List<String> filePaths;  //-----------------
    private UserDao userDao;
    public void setUserDao(UserDao userDao) {
        this.userDao = userDao;
    }
    public void setFilePaths(List<String> filePaths) {
        this.filePaths = filePaths;
    }
    public void save(){
        System.out.println("filePaths = " + filePaths);
        userDao.save();
    }
}

配置:

<!--先创建dao-->
    <bean id="userDao" class="com.wnxy.spring.dao.UserDao"></bean>
    <!--再创建service,注入dao-->
    <bean id="userService" class="com.wnxy.spring.service.UserService">
        <property name="userDao" value="#{userDao}"/>
        <property name="filePaths">
            <list>
                <value>/root/usr/mysql</value>
                <value>/root/usr/tomcat</value>
            </list>
        </property>
    </bean>

2.6 注解注入

1.在Spring中,一个类我们为它加上注解就可以被识别为一个Bean

例如你在一个类上加上一个@Component注解,它在配置类的@ComponentScan注解扫描的包下,或者把这给个类在配置类中加上@Bean注解,那么它就被识别为Bean,加入到Spring容器里。

@Configuration
@ComponentScan("com.imooc.spring.demo")
public class SpringBeanConfiguration {

    @Bean
    public FirstBean firstBean() {
        return new FirstBean();
    }
}
2.在一个Bean中调用另外一个Bean,就需要依赖注入。
@Component
public class SecondBean {
    private FirstBean firstBean;

    @Autowired
    public SecondBean(FirstBean firstBean) {
        this.firstBean = firstBean;
    }
    
    @Override
    public String toString() {
        return "SecondBean{firstBean=" + firstBean + '}';
    }
}

一个Bean要调用另一个Bean,直接调用是允许的,需要通过自动装配注解@Autowired进行依赖注入才能达成目的。

常用注解

注解 解释
@Configuration 标记的类是配置类
@ComponentScan(“包”) 指定哪个包,就扫描哪个包下的注解并识别。
@Autowired Bean的自动装配,可以标注在类的属性、方法及构造函数上。
@Component 把普通类标记为Bean,加入到容器里,并且是单例模式。
@Bean 定义一个Bean对象,加入到Spring容器里
@Order(数字) 容器加载Bean的优先级,数字越小优先级越高

场景

我们将构造方法注入、工厂方法注入或者属性注入三种注入方式进行细化,依赖注入的方式具体如下:

  • 构造方法注入Bean
  • Set方法注入Bean
  • 属性注入Bean
  • 集合的方式注入

示例

首先通过Configuration和@ComponentScan创建一个Spring的配置类。

@Configuration
@ComponentScan("com.imooc.spring.demo.bean")//项目的包名
public class SpringBeanConfiguration {
}

新建一个类FirstBean,通过@Component注解标记为Bean,加入到Spring容器里。

@Component
public class FirstBean {

}

通过构造方法注入

@Component
public class SecondBean {
    private FirstBean firstBean;

    @Autowired
    public SecondBean(FirstBean firstBean) {
        this.firstBean = firstBean;
    }
    
    @Override
    public String toString() {
        return "SecondBean{firstBean=" + firstBean + '}';
    }
}

通过Set方法注入

@Component
public class ThirdBean {
    private FirstBean firstBean;

    @Autowired
    public void setFirstBean(FirstBean firstBean) {
        this.firstBean = firstBean;
    }

    @Override
    public String toString() {
        return "ThirdBean{firstBean=" + firstBean + '}';
    }
}

通过属性注入

@Component
public class FourthBean {
    @Autowired
    private FirstBean firstBean;

    @Override
    public String toString() {
        return "FourthBean{firstBean=" + firstBean + '}';
    }
}

属性注入时,private私有属性,Spring是通过反射去加载它到Spring容器里的。

通过集合注入Bean

新建一个类FifthBean,标记为Bean。 加入一个List类型 的属性,用@Autowired注入。
在配置类中对加入一个返回值为List的方法或者加两个返回String的方法,使用Bean注解,这样就完成集合的赋值。

@Component
public class FifthBean {
    @Autowired
    private List<String> stringList;

    public List<String> getStringList() {
        return stringList;
    }
}
@Configuration
@ComponentScan("com.imooc.spring.demo")
public class SpringBeanConfiguration {

    @Bean
    public List<String> stringList() {
        List<String> list = new ArrayList<>();
        list.add("hello");
        list.add("imooc");
        return list;
    }
}
@Configuration
@ComponentScan("com.imooc.spring.demo")
public class SpringBeanConfiguration {

    @Bean
    public String firstString() {
        return "bye";
    }
    @Bean
    public String secondString() {
        return "imooc";
    }
}

第二种方式的优先级高于第一种,两种同时存在时Spring默认使用第二种,若要控制优先级要使用@Order注解来控制优先级顺序。

测试方法

class BeanDeoTest {

    @Test
    public void test() {
        ApplicationContext applicationContext =
        AnnotationConfigApplicationContext(SpringBeanConfiguration.class);
        SecondBean secondBean = applicationContext.getBean("secondBean", SecondBean.class);
        ThirdBean thirdBean = applicationContext.getBean("thirdBean", ThirdBean.class);
        System.out.println(secondBean.toString());
        System.out.println(thirdBean.toString());
    }
}

ApplicationContext用来获取配置类,getBean函数用来获取指定的Bean对象。

Tips

1. 只有@ComponentScan扫描的包下的被@Component标记的类才能识别为Bean。
2. 测试时你会发现所有的FristBean对象都是一个地址,说明@Component是单例模式的。

知识对比

对比几种装配Bean的方式

  • XML注入

    最原始的装配Bean的方式是XML语句,这也是Spring最早的注入方式。

<context:component-scan base-package="com.imooc.spring.demo"/>
<bean id="firstbean" class="FirstBean" />
  • 代码方式注入

    上文的测试类就是使用ApplicationContext进行上下文的获取,然后通过getBean进行Bean的注入。

ApplicationContext applicationContext = 
new AnnotationConfigApplicationContext(SpringBeanConfiguration.class);
SecondBean secondBean = applicationContext.getBean("secondBean", SecondBean.class);

注解注入的优点

  • 简洁明了,用注解代替大量的XML配置,降低了开发成本,节省了开发量。
  • 不用在.java文件和.xml文件中不断切换,提升开发的效率。

个人经验
使用统一装配规则,开发时,一般使用统一的装配规则,要么就是全部注解方式,要么就是全部XML方式。然后搭配BeanFactory 或者 ApplicationContext进行Bean的注入。非特殊情况避免注解和XMl结合使用。
推荐使用注解方式。当今互联网产品飞速迭代的情况下,成熟的互联网项目整体都是千万甚至上亿行代码,使用XML的成本会相当的高,注解已经是一种发展的趋势。

四、Spring注解使用

4.1 常用注解

注解作用:简化XML配置

创建对象相关注解:

@Component :标准一个普通的spring Bean类。 创建普通组件对象 同时@Component还是一个元注解

@Repository:标注一个DAO组件类。 创建持久化层 应用在dao层(数据访问层)。

@Service:标注一个业务逻辑组件类。 创建业务逻辑层组件 应用在service层(业务逻辑层)。

@Controller:标注一个控制器组件类。 创建控制层组件 应用在MVC层(控制层)。

​ DispatcherServlet会自动扫描注解了此注解的类,然后将web请求映射到注解了@RequestMapping的方法上。

这些都是注解在平时的开发过程中出镜率极高,@Component、@Repository、@Service、@Controller实质上属于同一类注解,用法相同,功能相同,区别在于标识组件的类型。 @Component可以代替@Repository、@Service、@Controller,因为这三个注解是被@Component标注的。


创建对象注解的注意点:

1、被注解的java类当做Bean实例,Bean实例的名称默认是Bean类的首字母小写,其他部分不变。@Service也可以自定义Bean名称,但是必须是唯一的!
2、尽量使用对应组件注解的类替换@Component注解,在spring未来的版本中,@Controller,@Service,@Repository会携带更多语义。并且便于开发和维护! 3、指定了某些类可作为Spring Bean类使用后,最好还需要让spring搜索指定路径,在Spring配置文件加入如下配置:

<!-- 自动扫描指定包及其子包下的所有Bean类 -->

<context:component-scan base-package=""/> ------->这个是注解扫描器


依赖注入相关注解:

  • @Autowired Spring提供的工具(由Spring的依赖注入工具(BeanPostProcessorBeanFactoryPostProcessor)自动注入)。可用于为类的属性、构造器、方法进行注值用于自动注入bean类型的对象,默认是按照类型自动装配,因此符合条件的对象不能超过一个,否则容器将不知道使用哪个对象,会报错。此时我们还可以通过@qualifier(“依赖的bean的id”)注解指明使用哪个对象来自动装配。

  • @Qualifier 配置@Autrwired一起使用;让@Autowired只根据名称注入; 一旦使用@Qualifier,不会根据类型注入了。

  • @Value 经常与Sping EL表达式语言一起使用,注入普通字符,系统属性,表达式运算结果,其他Bean的属性,文件内容,网址请求内容,配置文件属性值等。

    ​ 该注解的作用是将我们配置文件的属性读出来,有@Value(“${}”)@Value(“#{}”)两种方式

  • @Resource 注解:我们发现如果使用@autowired注解当需要指明注入的bean的id时还需要使用@qualifier注解,比较麻烦。此时我们还可以使用 @Resource 注解。@Resource注解单独使用时和@autowired效果一样,但是当需要指明注入的id时可以直接通过其name属性来指定,如,指明装配id为computer的bean时可以使用:@Resource(name=”computer”) 。 此时,@Resource注解相当于@autowired+@qualifier。

注意:

@Value的值有两类:
① ${ property : default_value }
② #{ obj.property? :default_value }
第一个注入的是外部配置文件对应的property,第二个则是SpEL表达式对应的内容。 那个
default_value,就是前面的值为空时的默认值。注意二者的不同,#{}里面那个obj代表对象。


依赖注入注解的注意点:

(1):相同点 @Resource的作用相当于@Autowired,均可标注在字段或属性的setter方法上。
(2):不同点
a :提供方 @Autowired是Spring的注解,@Resource是javax.annotation注解,而是来自于JSR-250,J2EE提供,需要JDK1.6及以上。
b :注入方式 @Autowired只按照Type 注入;@Resource默认按Name自动注入,也提供按照Type 注入;
c :属性
@Autowired注解可用于为类的属性、构造器、方法进行注值。默认情况下,其依赖的对象必须存在(bean可用),如果需要改变这种默认方式,可以设置其 required属性为false。

​ 还有一个比较重要的点就是,
​ @Autowired注解默认按照类型装配,如果容器中包含多个同一类型的Bean,那么启动容器时会报找不到指定类型bean的异常,解决办法是结合@Qualifier注解进行限定,指定注入的bean名称。 顺序是先根据类型注入: 自动去ioc容器中找dao该类型的对象注入;再根据名称注入:如果该类型的对象有多个,就根据字段的名称注入;前提:该类型的对象有多个 小结:先根据类型注入;如果类型有多个,再根据字段名称注入
​ @Resource有两个中重要的属性:name和type。name属性指定byName,如果没有指定name属性,当注解标注在字段上,即默认取字段的名称作为bean名称寻找依赖对象,当注解标注在属性的setter方法上,即默认取属性名作为bean名称寻找依赖对象。
需要注意的是,@Resource如果没有指定name属性,并且按照默认的名称仍然找不到依赖对象时, @Resource注解会回退到按类型装配。但一旦指定了name属性,就只能按名称装配了。
​ d:@Resource注解的使用性更为灵活,可指定名称,也可以指定类型 ;@Autowired注解进行装配容易抛出异常,特别是装配的bean类型有多个的时候,而解决的办法是需要在增加@Qualifier进行限定。

Spring整合junit单元测试

第一步:引入依赖

<dependencies>
     <!-- 提供了springIOC,AOP等 -->
     <dependency>
         <groupId>org.springframework</groupId>
         <artifactId>spring-context</artifactId>
         <version>5.2.12.RELEASE</version>
     </dependency>
	 
	 <!-- junit的Spring测试 -->
     <dependency>
         <groupId>org.springframework</groupId>
         <artifactId>spring-test</artifactId>
         <version>5.2.12.RELEASE</version>
     </dependency>
	 
	 <!-- junit测试 -->
     <dependency>
         <groupId>junit</groupId>
         <artifactId>junit</artifactId>
         <version>4.13</version>
     </dependency>
 </dependencies>

<!-- 注意!: spring-context的版本要和spring-test的版本要相同  -->
  • @Test:测试方法
  • @Ignore:被忽略的测试方法:加上之后,暂时不运行此段代码
  • @Before:每一个测试方法之前运行
  • @After:每一个测试方法之后运行
  • @BeforeClass:方法必须必须要是静态方法(static 声明),所有测试开始之前运行,注意区分 @Before
  • @AfterClass:方法必须要是静态方法(static 声明),所有测试结束之后运行,注意区分 @After

  • @ContextConfiguration 注解:
    locations 属性:用于指定配置文件的位置。如果是类路径下,需要用 classpath:表明
    classes 属性:用于指定注解的类。当不使用 xml 配置时,需要用此属性指定注解类的位置。

  • @RunWith(SpringJUnit4ClassRunner.class)

  • @RunWith:用于指定junit运行环境
    @ContextConfiguration:用于指定spring配置环境

// 指定配置类使用 classes 参数
@ContextConfiguration(classes = SpringConfiguration.class) 
// 指定配置文件使用 locations 参数
@ContextConfiguration(locations = "classpath:applicationContext.xml")

指定初始化和销毁回调

通过注解的方式,写在特定的方法上也可以指明Bean对象的初始化和销毁的回调函数。

  • @PostConstruct:写在方法上,指定此方法为初始化回调方法
  • @PreDestroy:写在方法上,指定此方法为销毁的回调方法
 	//指定初始化的方法
    @PostConstruct
    public void initMethod() {
        System.out.println("我是初始化方法");
    }

    //指定销毁之前执行的方法
    @PreDestroy
    public void destroyMethod() {
        System.out.println("我是对象销毁之前执行的方法");
    }

Spring事务模块注解

1、常用到的注解

在处理dao层或service层的事务操作时,譬如删除失败时的回滚操作。使用@Transactional 作为注解,但是需要在配置文件激活
@Transactional:表示所有类下所有方法都使用事务

@TransactionConfiguration:用于配置事务

<!-- 开启注解方式声明事务 -->
    <tx:annotation-driven transaction-manager="transactionManager" />

2、举例

@Service
public class CompanyServiceImpl implements CompanyService {
  @Autowired
  private CompanyDAO companyDAO;

  @Transactional(propagation = Propagation.REQUIRED, readOnly = false, rollbackFor = Exception.class)
  public int deleteByName(String name) {

    int result = companyDAO.deleteByName(name);
    return result;
  }
  ...
}

3、总结

事务的传播机制和隔离机制比较重要!

事务传播行为类型 说明
PROPAGATION_REQUIRED 如果当前没有事务,就新建一个事务,如果已经存在一个事务中,加入到这个事务中。这是最常见的选择。
PROPAGATION_SUPPORTS 支持当前事务,如果当前没有事务,就以非事务方式执行。
PROPAGATION_MANDATORY 使用当前的事务,如果当前没有事务,就抛出异常。
PROPAGATION_REQUIRES_NEW 新建事务,如果当前存在事务,把当前事务挂起。
PROPAGATION_NOT_SUPPORTED 以非事务方式执行操作,如果当前存在事务,就把当前事务挂起。
PROPAGATION_NEVER 以非事务方式执行,如果当前存在事务,则抛出异常
PROPAGATION_NESTED 如果当前存在事务,则在嵌套事务内执行。如果当前没有事务,则执行与PROPAGATION_REQUIRED类 似的操作

readOnly : 事务的读写属性,取true或者false,true为只读、默认为false
rollbackFor : 回滚策略,当遇到指定异常时回滚。譬如上例遇到异常就回滚
timeout (补充的) : 设置超时时间,单位为秒
isolation : 设置事务隔离级别,枚举类型,一共五种

类型 说明
DEFAULT 采用数据库默认隔离级别
READ_UNCOMMITTED 读未提交的数据(会出现脏读取)
READ_COMMITTED 读已提交的数据(会出现幻读,即前后两次读的不一样)
REPEATABLE_READ 可重复读,会出现幻读
SERIALIZABLE 串行化 (对资源消耗较大,一般不使用)

标签:框架,Spring,class,Bean,注解,public,注入
From: https://www.cnblogs.com/amor2818/p/17154929.html

相关文章

  • SpringCloud 源码学习笔记2——Feign声明式http客户端源码分析
    系列文章目录和关于我一丶Feign是什么Feign是一种声明式、模板化的HTTP客户端。在SpringCloud中使用Feign,可以做到使用HTTP请求访问远程服务,就像调用本地方法一一样的......
  • SpringMVC
    目录二、SpringMVC简介2.1什么是SpringMVC2.2.SpringMVC的作用2.3.SpringMVC原理2.4.SpringMVC执行流程:2.4.1涉及组件分析:2.5搭建SpringMVC项目环境:2.5.1、代码实现第一......
  • Spring注解补充(一)
    注解补充挑一些常用,但是深入不多的总结一下。Bean的声明周期在@Bean注解中,添加init属性和destroy属性@Bean(initMethod="initMethod",destroyMethod="destroyMe......
  • SpringBoot入门
    SpringBoot概念SpringBoot提供了一种快速使用Spring的方式,基于约定优于配置的思想,可以让开发人员不必在配置与逻辑业务之间进行思维的切换,全身心的投入到逻辑业务的代码......
  • 【学习笔记】SpringMVC执行原理
    SpringMVC执行原理执行步骤每一步的解释如下:DispatcherServlet表示前端控制器,是整个SpringMVC的控制中心,用户发出请求,DispatcherServlet接受请求并拦截请求请求的......
  • SpringBoot
    springboot什么是springbootspringboot简介:Springboot是基于spring开发的,Springboot本身不提供spring的核心特性和拓展功能,只能用于快速,敏捷的开发新一代基于spring框......
  • java security 详解_Spring Security入门教程
    SpringSecurity的简单使用简介SSM整合Security是比较麻烦的,虽然Security的功能比Shiro强大,相反却没有Shiro的使用量多SpringBoot出现后简化了Spring系列的配置......
  • ava——spring boot集成RabbitMQ——如何实现手动ack
                  =============================================================           ......
  • java——spring boot集成RabbitMQ——spring boot实现路由模式——消费者
    pom文件:<?xmlversion="1.0"encoding="UTF-8"?><projectxmlns="http://maven.apache.org/POM/4.0.0"xmlns:xsi="http://www.w3.org/2001/XMLSchema-instanc......
  • java——spring boot集成RabbitMQ——spring boot实现路由模式——生产者
    pom文件:<?xmlversion="1.0"encoding="UTF-8"?><projectxmlns="http://maven.apache.org/POM/4.0.0"xmlns:xsi="http://www.w3.org/2001/XMLSchema-instanc......