spring 注解版

it2023-09-05  94

相信使用过spring的朋友都被配置文件支配过,尤其是整合ssm,那简直就是配置地狱,但随着springboot的兴起,spring的注解也开始流行起来,也可以用注解来进行配置。

首先这是一个建立在maven工程的spring项目,我用的是idea。

导入依赖 pom.xml

<dependencies> <!-- https://mvnrepository.com/artifact/org.springframework/spring-context --> <!--spring依赖--> <dependency> <groupId>org.springframework</groupId> <artifactId>spring-context</artifactId> <version>4.3.12.RELEASE</version> </dependency> <!--单元测试依赖--> <dependency> <groupId>junit</groupId> <artifactId>junit</artifactId> <version>4.13</version> <scope>test</scope> </dependency> <!--lombok插件,快速编写实体类--> <dependency> <groupId>org.projectlombok</groupId> <artifactId>lombok</artifactId> <version>1.18.12</version> </dependency> </dependencies>

实体类 com.sixteen.entity.Person.java

package com.sixteen.entity; import lombok.Data; @Data public class Person { private String name; private Integer age; }

建立一个包用来放置各种配置文件 com.sixteen.config.SpringConfig.java

package com.sixteen.config; import com.sixteen.entity.Person; import org.springframework.context.annotation.Bean; import org.springframework.context.annotation.ComponentScan; import org.springframework.context.annotation.Configuration; @Configuration @ComponentScan(basePackages = {"com.sixteen"})//有过滤规则 public class SpringConfig { @Bean("person01")//默认是单例模式 public Person person(){ return new Person(); } }

@Configuration是配置注解,声明此类是一个配置类,可以创建多个配置类,但不要忘了注解,运行代码时会加载此类,与xml配置文件一样的作用。

@Bean注解就类似于xml配置文件中的 <bean></bean>标签

@Bean("person01")//默认是单例模式 public Person person()

默认注册在IOC时以方法名为bean的id(即xml中bean标签的id),也可以这样@Bean("person01"),在@Bean注解内给注册的类改个名字。

不过这样注册的bean默认是单例模式,也就是说只要获取两次以上或者多次获取同一种bean,其实获取的都是同一个bean。

通过@Scope注解可以改变模式

/** * Specifies the name of the scope to use for the annotated component/bean. * <p>Defaults to an empty string ({@code ""}) which implies * {@link ConfigurableBeanFactory#SCOPE_SINGLETON SCOPE_SINGLETON}. * @since 4.2 * @see ConfigurableBeanFactory#SCOPE_PROTOTYPE prototype * @see ConfigurableBeanFactory#SCOPE_SINGLETON singleton * @see org.springframework.web.context.WebApplicationContext#SCOPE_REQUEST request * @see org.springframework.web.context.WebApplicationContext#SCOPE_SESSION session * @see #value * * prototype 多例 ioc容器启动不调用方法,每次获取就调用方法,多次获取多次调用 * singleton 单例(默认值) ioc容器启动就会调用方法创建对象放到IOC容器中,以后每次获取直接从容器拿 * request 同一次请求创建一个实例 * session 同一个session创建一个实例 * * 懒加载:(针对于单实例) * 单例:默认在IOC容器启动后创建对象 * 懒加载:容器启动不创建对象,第一次使用(获取)bean创建对象,并初始化 * @return */ @Scope("prototype")//这样就是多例模式了 @Bean("person01") public Person person(){ return new Person(); }

@ComponentScan就是xml文件中的context标签那个组件扫描,basePackages是一个数组,可以扫描多个包,也可以使用扫描规则或者自定义扫描规则(具体详情查看@ComponentScan注解源码),在配置类使用这个注解后,会去扫描包内带有@Controller,@Service,@Repository,@Component注解的类,并将其注册到IOC容器中。

因为现在是用注解方式配置spring 所以在运行代码时也有所改变 main方法

ApplicationContext context = new AnnotationConfigApplicationContext(SpringConfig.class);

SpringConfig.class就是你的注解配置类,得到的context就和new ClassPathXmlApplicationContext()返回的对象是一样的。

spring中有个注解在后续的springboot中出现的非常多 那就是 @Conditional,这个注解可以作用在类上和方法上,

放在类上,像这样

@Conditional(xxx.class) @Configuration @ComponentScan(basePackages = {"com.sixteen"})//有过滤规则 public class SpringConfig { @Bean("person01")//默认是单例模式 public Person person(){ return new Person(); } }

在类上的意思是,如果条件满足,这个配置类才会被加载到IOC容器中。

放在配置类中的方法上,像这样

//@Conditional()参数: Class<? extends Condition>[] value(); @Conditional(xxx.class) @Bean("person01") public Person person()

xxx.class需要实现Condition这个接口,注意不要导错了包

当满足条件时才会将这个bean注册在IOC容器中。

Condition.class

public interface Condition { /** * Determine if the condition matches. * @param context the condition context * @param metadata metadata of the {@link org.springframework.core.type.AnnotationMetadata class} * or {@link org.springframework.core.type.MethodMetadata method} being checked. * @return {@code true} if the condition matches and the component can be registered * or {@code false} to veto registration. */ boolean matches(ConditionContext context, AnnotatedTypeMetadata metadata); }

Condition中的matches方法返回的boolean值代表是否满足条件。

可能我描述的不是很详细或者完整,可以自行点开源码进行阅读,也可以去官方文档或者百度查找进行更一步的深入了解。

spring的注解暂时先说到这,后续还会持续更新。

最新回复(0)