spring-aop与auto

1AOP



(1)@Component // 声明为一个普通组件,放入spring的容器中,才可以生效
(2)@Aspect // 声明当前类是一个切面
(3)重用切入点表达式:@Pointcut,避免切入点表达式的重复定义,方便维护
 (4)前置通知(增强):@Before,在目标方法执行前,自动执行此方法(通过代理实现)   @Before("execution(* com.kgc.spring.aspectj.*.*(..))") 
(5)后置通知: @After,在目标方法执行后,自动执行,特点:此通知无法获取目标方法的返回值,它的执行跟目标方法是否抛出异常无关(目标方法执行异常,不影响此方法的执行)
@After("execution(* com.kgc.spring.aspectj.*.*(..))")
(6) 返回通知: @AfterReturning,在目标方法返回结果后,自动执行,可以获取目标方法的返回值,但是要求@AfterReturning增加属性returning,指定一个参数名,且此参数名必须返回通知方法的一个形参名一致,用于接收目标方法的返回
 @AfterReturning(value = "execution(* com.kgc.spring.aspectj.*.*(..))", returning = "result")

(7)异常抛出通知: @AfterThrowing,在目标方法抛出异常后,自动执行,可以获取目标方法的抛出异常信息,但是要求@AfterThrowing增加属性throwing,指定一个参数名,且此参数名必须返回通知方法的一个形参名一致,用于接收目标方法的异常
@AfterThrowing(value = "execution(* com.kgc.spring.aspectj.*.*(..))", throwing = "ex")

(8)环绕通知:@Around,可以看做是上面四种通知的结合体,一般不建议共用(防止冲突),作用:可以让开发人员在环绕通知的处理方法中,根据不同的业务逻辑,决定是否发起对目标方法的调用
 @Around("execution(* com.kgc.spring.aspectj.*.*(..))")

(9)通用切入点表达式含义:"execution(* com.kgc.spring.aspectj.*.*(..))"* 
*  第一个*:代表任意的修饰符,任意的返回值类型
*  第二个*:任意类
*  第三个*:任意的方法
*  第四个..:任意类型和个数的形参
*/
(10)@Order(1) // 指定切面优先级,一般都是int型整数,值越小,优先级越高,默认是int最大值(2的31次方-1)

(11)<!--  组件扫描  -->
<context:component-scan base-package="com.kgc.spring.aspectj"/>

<!--  基于注解方式实现Aspect切面  -->
<!--  作用:当spring的容器检测到此配置项,会自动将Aspect切面匹配的目标类创建代理对象,放入容器,默认使用的是jdk的动态代理  -->
<aop:aspectj-autoproxy/>

2AUTO

(1)

// 以前写法:代码耦合度太高,一旦实现类发生修改,必须修改当前类的代码,更改实现类,无法实现自动识别
// private UserService userService = new UserServiceImpl();

// 组件自动装配,可以实现实体属性类型的自动装配,自动到spring的容器中,根据当前属性的类型或者名称进行注入,如果容器中能匹配到,就直接将实例对象注入到当前实体属性上,无序手动指定

// @Autowired自动装配原理:首先会根据byType方式,进行自动装配,如果能唯一匹配,直接执行自动装配,如果不能唯一匹配(存在同类型多个实例对象),会再次尝试使用byName方式,根据当前实体属性名,到容器中进行匹配(容器中bean的id值),如果能唯一匹配,仍会执行自动装配,如果匹配失败,直接抛出异常
// 默认情况下,@Autowired注解标识的实体属性,必须被装配,如果装配失败,就直接抛出异常,如果不需要校验必须被装配(项目启动,如果装配失败,项目是起不来),通过指定required = false,去除必须执行自动装配的校验(即便容器中找不到装配的实例,也不会抛出异常)
// 如果自动装配,容器中存在多个同类型的bean对象,可以使用注解@Qualifier("容器中同类型多个bean的某个id值"),实现指定到容器中,找对应的bean实例对象,进行自动装配

// 底层是如何做的:在指定要扫描的包时,<context:component-scan> 元素会自动注册一个bean的后置处理器:AutowiredAnnotationBeanPostProcessor的实例。该后置处理器可以自动装配标记了@Autowired、@Resource或@Inject注解的属性。

// @Autowired(required = false) // 如果需要允许不必须被装配,可以指定required属性为 false,如果不能自动装配也不会报错,项目正常启动
@Resource // @Autowired是spring提供的,@Resource是jdk提供自动装配注解,装配原理和@Autowired是相反
@Repository // 持久层注解,标识为持久层组件
@Service("myUserService") // 业务层注解,标识为业务层组件,可以起别名
@Autowired // 只要增加此注解,代表实体属性,必须被装配,否则报错,项目启动失败
@Qualifier("userRepositoryMybatisImpl") // @Qualifier注解,如果有多个匹配类型的实例对象,可以指定要装配的bean的id值,实现自动装配,推荐用法
private UserRepository userRepository;// 类型有1个,类型匹配
 @Service 强调:组件注解,是用于可以被spring扫描到,创建当前类的实例对象,放到spring的容器中,所以,注解不能加在接口上,都是加在接口的实现类上

<!--  基于spring的注解方式实现自动装配  -->
<!--  组件扫描:注解标识的组件,必须通过组件扫描配置,才可以添加到spring的容器中  -->
<!--
    spring创建容器对象时,如果解析到component-scan组件扫描配置,会将base-package指定的基包(父包)及其子包中所有增加了分层注解的类,自动创建实例对象,放入容器中,交给spring容器管理,省去了手动配置bean的繁琐操作
    1、默认情况下:spring自动将分层注解(@Controller,@Service, @Repository,@Component)标识的类(不是接口),自动创建实例对象放入容器中,使用的bean的标识id值为:对应类名首字母小写
    就相当于帮我们手动添加了配置:<bean id="分层注解标识类的类名首字母小写" class="分层注解标识类的全类名">...</bean>
    2、如果不使用默认的类名首字母小写,可以使用注解的value属性,指定一个自定义的id值,如:@Service(value = "自定义的id值"),注解只有value属性,可以省略value指定,简化为:@Service("自定义的id值")
    3、实际上,Spring框架没有能力识别一个组件到底是不是它所标记的类型,即便使用@Component注解,添加到@Controller组件的控制层类上,也可以自动创建实例对象放入容器
    4、分组组件注解的目的:就仅仅是为了方便开发人员明确当前注解标注的类所对应的角色,在使用上,没有什么区别的,建议使用时,按照官方定义的组件类型进行使用,不要乱用,防止组件模糊不清
-->
<context:component-scan base-package="com.kgc.spring.annotation">
    <!--  1、指定扫描(包含扫描):只会扫描指定的类或者某类组件(使用分层注解),加入到容器中,但是必须要配合父标签的use-default-filters使用,默认值是true,就是全部扫描,指定扫描是无效的,如果要生效必须将其改为false  -->
    <!--  指定扫描某类组件,type="annotation",expression="某类组件注解的全类名" -->
    <!--<context:include-filter type="annotation" expression="org.springframework.stereotype.Controller"/>-->
    <!--  指定扫描某个类,type="assignable",expression="某个类的全类名" 了解,很少使用-->
    <!--<context:include-filter type="assignable" expression="com.kgc.spring.annotation.controller.UserController"/>-->
    
    <!--  2、排除扫描(剔除扫描):直接排除指定的类或者某类组件(使用分层注解),不加入到容器中,除了排除外的其它组件,仍然会被添加到容器中,不需要配合父标签的use-default-filters使用,默认就是全部扫描,排除就是在全部扫描基础上,剔除的  -->
    <!--  排除扫描某类组件,type="annotation",expression="某类组件注解的全类名" -->
    <!--<context:exclude-filter type="annotation" expression="org.springframework.stereotype.Controller"/>-->
</context:component-scan>

<!--
    spring中bean的自动装配方式:
        1、byType:根据类型自动装配
            根据实例属性的类型,到容器中,根据类型进行唯一匹配,如果可以匹配到对应类型的bean的实例,就会执行自动装配,如果不能唯一匹配(同类型的bean有多个),会报错,并装配失败
            如果容器中匹配不到对应类型的bean,不会报错,不执行自动装配,实体属性对应为null
       2、byName:根据名称自动装配
            根据实体属性的属性名,到容器中,跟bean的id属性值,进行唯一匹配,如果能成功匹配,执行自动装配,如果匹配不到,不执行自动装配,实体属性为null,不会存在匹配多个情况(bean的id值是唯一)
-->

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值