Spring框架(六):Spring相关注解复习

本文将对Spring中的注解进行大致说明
(备注:假如想要查询某个注解,可以使用快捷键Ctrl+F查询)

0、创建对象

附: 下面四种都可以创建出对象,功能完全一样,只是约定使用的层不同
(1)@Component ——对象创建(当我们的类不属于各种归类的时候,就可以使用@Component来标注这个类)
(2)@Service——用于业务层的bean对象创建——对应serviceimpl实现类
(3)@Controller——用于表现层的bean对象创建——对应controller类
(4)@Repository——用于数据层的bean对象创建——对应Dao接口

1、SpringConfig核心配置类

@Configuration //声明当前类为Spring配置类
@ComponentScan("com.itheima")//开启注解扫描,扫描路径:相对于root源文件的路径,作用:如果没有开启包注解扫描,那么在类或者方法上配置的注解是毫无意义的.(
@PropertySource("classpath:jdbc.properties")//加载外部文件,classpath:相对于resources包下文件
@EnableAspectJAutoProxy///告诉SpringConfig 开启注解开发AOP功能
@Import({JdbcConfig.class,MybatisConfig.class})//导入其他配置类的信息(目的:将配置类分类,然后导入Spring配置类)
@EnableTransactionManagement//开启注解式事务驱动
public class SpringConfig {
}

2、其他配置类

例:JdbcConfig
@Value 注入字符串,这里使用EL表达式(搭配@PropertySource注解使用,获取外部文件的属性)
@Bean:将(方法的返回值)上传/注册到Spring容器中

public class JdbcConfig {
    @Value("${jdbc.driver}")
    private String driver;
    @Value("${jdbc.url}")
    private String url;
    @Value("${jdbc.username}")
    private String userName;
    @Value("${jdbc.password}")
    private String password;

    @Bean//上传方法的返回对象ds到容器中
    public DataSource dataSource(){
        DruidDataSource ds = new DruidDataSource();
        ds.setDriverClassName(driver);
        ds.setUrl(url);
        ds.setUsername(userName);
        ds.setPassword(password);
        return ds;
    }
}

3、aop.切面类(通知类)

@Component//创建/注册对象到Spring容器中
@Aspect//设置当前类为切面类,告知Spring容器这是一个切面的通知类
(与@EnableAspectJAutoProxy搭配Spring核心配置类的使用–告诉SpringConfig 开启注解开发AOP功能)

@Pointcut(“execution(boolean com.itheima.service.Service.(,))”)//设置切入点,要求配置在方法上方

@Component
@Aspect
public class DataAdvice {
    @Pointcut("execution(boolean com.itheima.service.*Service.*(*,*))")
    private void servicePt(){}

    //该环绕通知的目的:获取并处理原始方法的字符串参数,去掉两边的空格
    @Around("servicePt()")
    public Object trimStr(ProceedingJoinPoint pjp) throws Throwable {
        Object[] args = pjp.getArgs();
        for (int i = 0; i < args.length; i++) {
            //判断参数是不是字符串类型
            if(args[i].getClass().equals(String.class)){
                args[i] = args[i].toString().trim();
            }
        }
        Object ret = pjp.proceed(args);
        return ret;
    }
}

4、五种通知(通知也是写在通知类中)

  1. @Before(“切入点”),前置通知——通知方法在切入点(方法前)运行
  2. @After(“切入点”),后置通知——通知方法在切入点(方法后)运行
  3. @Around(“切入点”),环绕通知(重点)——前后都运行
  4. @AfterReturning(value = “pt()”,returning = “ret”),
    返回后通知(了解):返回后通知,在原始方法执行完毕后运行,且原始方法执行过程中未出现异常现象
  5. @AfterThrowing(value = “pt()”,throwing = “t”),
    抛出异常后通知(了解):抛出异常后通知,在原始方法执行过程中出现异常后运行

附:JoinPoint:用于描述切入点的对象,必须配置成通知方法中的第一个参数,可用于获取原始方法调用的参数(ProceedingJoinPoint接口是JoinPoint的子接口)


@Component
@Aspect
public class MyAdvice {
    @Pointcut("execution(* com.itheima.dao.BookDao.findName(..))")
    private void pt(){}

    //JoinPoint:用于描述切入点的对象,必须配置成通知方法中的第一个参数,可用于获取原始方法调用的参数
    @Before("pt()")
    public void before(JoinPoint jp) {
        Object[] args = jp.getArgs();
        System.out.println(Arrays.toString(args));
        System.out.println("before advice ..." );
    }

    @After("pt()")
    public void after(JoinPoint jp) {
        Object[] args = jp.getArgs();
        System.out.println(Arrays.toString(args));
        System.out.println("after advice ...");
    }

    //ProceedingJoinPoint:专用于环绕通知,是JoinPoint子类,可以实现对原始方法的调用
    @Around("pt()")
    public Object around(ProceedingJoinPoint pjp) {
        Object[] args = pjp.getArgs();
        System.out.println(Arrays.toString(args));
        args[0] = 666;
        Object ret = null;
        try {
            ret = pjp.proceed(args);
        } catch (Throwable t) {
            t.printStackTrace();
        }
        return ret;
    }

    //设置返回后通知获取原始方法的返回值,要求returning属性值必须与方法形参名相同
    @AfterReturning(value = "pt()",returning = "ret")//如果原始方法中有返回值,就将该返回值放到形参ret中去
    public void afterReturning(JoinPoint jp,Object ret) {
        System.out.println("afterReturning advice ..."+ret);
    }

    //设置抛出异常后通知获取原始方法运行时抛出的异常对象,要求throwing属性值必须与方法形参名相同
    @AfterThrowing(value = "pt()",throwing = "t")
    public void afterThrowing(Throwable t) {
        System.out.println("afterThrowing advice ..."+t);
    }
}

5、自动装配

5.1根据类型自动装配(注入引用类型)
@Autowired

5.2 根据bean名称装配
@Autowired
@Qualifier(“id名称”):自动装配bean时按bean名称装配

@Service
public class BookServiceImpl implements BookService {
    //@Autowired:注入引用类型,自动装配模式,默认按类型装配
    
    @Autowired
    @Qualifier("bookDao")//@Qualifier:自动装配bean时按bean名称装配
    private BookDao bookDao;

    public void save() {
        System.out.println("book service save ...");
        bookDao.save();
    }
}

附:注解开发的作用范围与生命周期管理(了解)

@Scope设置bean的作用范围
//singleton 单实例对象(运行两次都是同一个对象)
//prototype 多实例对象

@PostConstruct设置bean的初始化方法

@PreDestroy设置bean的销毁方法

package com.itheima.dao.impl;

import com.itheima.dao.BookDao;
import org.springframework.context.annotation.Scope;
import org.springframework.stereotype.Repository;
import javax.annotation.PostConstruct;
import javax.annotation.PreDestroy;


@Repository
//@Scope设置bean的作用范围
//singleton 单实例对象(运行两次都是同一个对象)
// prototype 多实例对象
@Scope("singleton")
public class BookDaoImpl implements BookDao {

    public void save() {
        System.out.println("book dao save ...");
    }
    //@PostConstruct设置bean的初始化方法
    @PostConstruct
    public void init() {
        System.out.println("init ...");
    }
    //@PreDestroy设置bean的销毁方法
    @PreDestroy
    public void destroy() {
        System.out.println("destroy ...");
    }

}

附:@Alias给pojo起别名

@Alias("user")
public class User{
    ...}

6、事务

@EnableTransactionManagement//开启注解式事务驱动
@Transactional的作用:配置当前接口方法具有事务(业务层接口或这实现类)

//配置当前接口方法具有事务
@Transactional(rollbackFor = IOException.class)//rollbackFor设置事务回滚异常(class)
    public void transfer(String out,String in ,Double money) ;

专栏文章:
Spring框架(一):概述及简单使用(基于XML方式)

Spring框架(二):注解开发及快速入门

Spring框架(三):Spring整合Mybaits、Junit

Spring框架(四):AOP面向切面编程

Spring框架(五):Spring事务简述(注解方式)

Spring框架(六):Spring注解简述

  • 1
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值