终于到注解编程了,天天用天天用,但依旧啥也不会。使用注解说白了就是对xml配置文件的简化。这节记录几个基础注解,看下效果。(这节大部分内容都是贴笔记的,笔记很细,也比较简单)

一、注解的概念
1、注解编程

指的是在类或者方法上加入特定的注解(@XXX),完成特定功能的开发。

2、使用注解编程的好处

注解开发方便,开发速度大大提高,并且注解编程是现在的开发潮流。(Spring2.x引入注解 Spring3.x完善注解 SpringBoot普及 推广注解编程)

3、注解的作用

替换XML配置形式,简化配置

22.PNG

不用实现接口了,而且方法名也能自定义了,加注解就行。通过注解的方式,在功能调用者和功能提供者之间达成约定,进而进行功能的调用。因为注解应用更为方便灵活,所以在现在的开发中,更推荐通过注解的形式

23.PNG

4、Spring注解的发展历程
1. Spring2.x开始支持注解编程 @Component @Service @Scope..
目的:提供的这些注解只是为了在某些情况下简化XML的配置,作为XML开发的有益补充。
2. Spring3.x @Configuration @Bean..
目的:彻底替换XML,基于纯注解编程
3. Spring4.x SpringBoot
提倡使用注解常⻅开发
5、Spring注解开发存疑
问题: Spring基于注解进行配置后,还能否解耦合呢?
回答: 在Spring框架应用注解时,如果对注解配置的内容不满意,可以通过Spring配置文件进行覆盖
二、Spring的基础注解(Spring2.X)

这个阶段的注解,仅仅是简化XML的配置,并不能完全替代XML

1、对象创建相关注解
需要在配置文件中加入标签:<context:component-scan base-package="com.jin">
作用是让Spring框架在设置包及其子包中扫描对应的注解,使其生效。

@Component

作用:替换原有spring配置文件中的<bean标签
注意:
id属性 component注解 提供了默认的设置方式 首单词首字母小写
class属性 通过反射获得class内容

24.PNG

几个细节:

显示指定工厂创建对象的id值,在该注解直接加参数即可: @Component("u")
Spring配置文件覆盖注解配置内容:
在applicationContext.xml中加入:
<bean id="u" class="com.jin.bean.User">
        <property name="id" value="199" />
    </bean>
需要id值 class的值 要和 注解中的设置保持一值,可以实现覆盖,可用给配置文件注入值做对照实验,注解方式getId()会取取null,xml配置方式会得到199

@Component的衍生注解

@Repository ---> XXXDAO
    @Repository
    public class UserDAO{

    }
@Service
    @Service
    public class UserService{

    }
@Controller
    @Controller
    public class RegAction{
    }
注意:本质上这些衍生注解就是@Component
    作用 <bean
    细节 @Service("s")
目的:更加准确的表达一个类型的作用
注意:Spring整合Mybatis开发过程中 不使用@Repository @Component

@Scope注解

作用:控制简单对象创建次数
注意:不添加@Scope Spring提供默认值 singleton
<bean id="" class="" scope="singleton|prototype"/>

可改变注解参数值,输出两个对象值对照比较:

//用于测试:@Scope注解
    @org.junit.Test
    public void test2(){
        ClassPathXmlApplicationContext ctx = new ClassPathXmlApplicationContext("applicationContext.xml");
        Customer customer = (Customer) ctx.getBean("customer");
        Customer customer1 = (Customer) ctx.getBean("customer");
        System.out.println("customer = " + customer);
        System.out.println("customer1 = " + customer1);
    }

@Lazy注解

作用:延迟创建单实例对象
注意:一旦使用了@Lazy注解后,Spring会在使用这个对象时候,进行这个对象的创建
<bean id="" class="" lazy="false"/>

同样,对照实验,加上@Lazy,对象会在getBean()时才被创建,否则在工厂加载配置文件时就被创建

    //用于测试:@Lazy注解
    @org.junit.Test
    public void test3(){
        ClassPathXmlApplicationContext ctx = new ClassPathXmlApplicationContext("applicationContext.xml");
//        Account account = (Account) ctx.getBean("account");
//        System.out.println("account = " + account);
    }

生命周期方法相关注解

工厂创建后调用初始化方法,关闭调用销毁方法:

package com.jin.life;

import org.springframework.stereotype.Component;

import javax.annotation.PostConstruct;
import javax.annotation.PreDestroy;

/**
 * @author jinyunlong
 * @date 2021/12/23 15:14
 * @profession ICBC锅炉房保安
 */
@Component
public class Product {
    @PostConstruct
    public void myInit(){
        System.out.println("Product.myInit");
    }

    @PreDestroy
    public void myDestory(){
        System.out.println("Product.myDestory");
    }
}

    //用于测试:生命周期相关注解
    @org.junit.Test
    public void test4(){
        ClassPathXmlApplicationContext ctx = new ClassPathXmlApplicationContext("applicationContext.xml");
        Product product = (Product) ctx.getBean("product");
        System.out.println("product = " + product);
        ctx.close();
    }

注意: 上述的2个注解并不是Spring提供的,由JSR(JavaEE规范)520提供

2、注入相关注解

用户自定义类型注入使用@Autowired

25.PNG
根据注解放置位置可以发现对应的应该是set注入,@Autowired注解需要注意的细节:

1. Autowired注解基于类型进行注入 [推荐]
基于类型的注入:注入对象的类型,必须与目标成员变量类型相同或者是其子类(实现类)
2. Autowired Qualifier 基于名字进行注入 [了解]
基于名字的注入:注入对象的id值,必须与Qualifier注解中设置的名字相同
3. Autowired注解放置位置
   a) 放置在对应成员变量的set方法上
   b) 直接把这个注解放置在成员变量之上,Spring通过反射直接对成员变量进行注入(赋值)[推荐]
4. JavaEE规范中类似功能的注解
   JSR250 @Resouce(name="userDAOImpl") 基于名字进行注入
          @Autowired()
          @Qualifier("userDAOImpl")
   注意:如果在应用Resource注解时,名字没有配对成功,那么他会继续按照类型进行注入。
   JSR330 @Inject 作用 @Autowired完全一致 基于类型进行注入 ---》EJB3.0

JDK类型的注入使用@Value注解完成

1. 设置xxx.properties
   id = 10
   name = suns
2. Spring的工厂读取这个配置文件
   <context:property-placeholder location=""/>
3. 代码
   属性 @Value("${key}")

@PropertySource注解

1. 作用:用于替换Spring配置文件中的<context:property-placeholder location=""/>标签
2. 开发步骤
   1. 设置xxx.properties
          id = 10
          name = suns
   2. 应用@PropertySource
   3. 代码
      属性 @Value()

@Value注解使用细节

@Value注解不能应用在静态成员变量上
@Value注解+Properties这种方式,不能注入集合类型(Spring提供新的配置形式 YAML YML (SpringBoot))
3、扫描注解

要使注解生效,还需要在配置文件中配置扫描包的标签:

<context:component-scan base-package="com.baizhiedu"/>
使当前包 及其 子包的注解生效

指定包(类)中注解生效(不生效)的配置方法,分为排除方法和包含方法:

排除方法:
    <context:component-scan base-package="com.jin">
<!--        <context:exclude-filter type="assignable" expression="com.jin.injection.Category"/>-->
<!--        <context:exclude-filter type="annotation" expression="org.springframework.stereotype.Service"/>-->
<!--        <context:exclude-filter type="assignable" expression="com.jin.life.Product"/>-->
<!--        <context:exclude-filter type="aspectj" expression="com.jin.injection..*"/>-->
    </context:component-scan>

包含方法:
<!--    <context:component-scan base-package="com.jin" use-default-filters="false">-->
<!--        <context:include-filter type="assignable" expression="com.jin.injection.Category"/>-->
<!--        <context:include-filter type="annotation" expression="org.springframework.stereotype.Repository"/>-->
<!--    </context:component-scan>-->
标签类型的用法:
type:assignable:排除特定的类型 不进行扫描
     annotation:排除特定的注解 不进行扫描
     aspectj:切入点表达式
             包切入点: com.baizhiedu.bean..*
             类切入点: *..User
     regex:正则表达式
     custom:自定义排除策略框架底层开发
4、注解开发的思考
Spring注解配置和配置文件的配置 互通
例如下:通过property标签获取到@Repository创建的对象
@Repository
public class UserDAOImpl{
}
public class UserServiceImpl{
   private UserDAO userDAO;
   set get
}
<bean id="userService" class="com.baizhiedu.UserServiceImpl">
   <property name="userDAO" ref="userDAOImpl"/>
</bean>
什么情况下使用注解 什么情况下使用配置文件
@Component 替换 <bean
基础注解(@Component @Autowired @Value) 程序员开发类型的配置
1. 在程序员开发的类型上 可以加入对应注解 进行对象的创建
User UserService UserDAO UserAction
2. 应用其他非程序员开发的类型时,还是需要使用<bean 进行配置的
SqlSessionFactoryBean MapperScannerConfigure
5、SSM整合开发(半注解开发)

对照Spring(8),DAO层开发不用变(非程序员开发),只需要在Service层和Controller层部分地方将XML配置该为注解即可。

别忘了在配置文件中加入扫描注解的标签。


标题:Spring(9)
作者:jyl
地址:http://www.jinyunlong.xyz/articles/2021/12/24/1640342317189.html