Spring注解

1.@Configuration

作用在类上,表名被@Configuration修饰的类是一个配置类。主要与@Bean联合使用将第三方jar类注入到容器中

@Configuration 
public class MyConfig {

 

2.@Bean

主要与@Configuration注解联合使用,作用在方法上,将方法返回的类注入到容器中。注入容器中的Bean Id 默认为方法名.

主要属性:

name 同 value: 用于自定义注入容器中Bean的Id;是一个数组,可以为这个bean定义多个id

@Bean(name = {"c1","c2"}) 
public C c(){

initMethod: 指定初始化方法

destroyMethod:指定Bean的清除方法

 

3.@ComponentScan

指定需要扫描的包,将标有@Component,@Repository,@Service,@Controller等注解的类注入到容器中

主要属性:

basePackages 同 value 指定需要扫描的包,可以指定多个

basePackageClasses:指定扫描的类

excludeFilters:根据type,classes指定不扫描的类,默认根据注解方式进行排除

@ComponentScan(basePackages = {"com.java"}, 
excludeFilters = { @ComponentScan.Filter(type = FilterType.ANNOTATION,
 classes={Controller.class}) })

 

includeFilters:根据type,classes指定需要被包含的类,必须使用useDefaultFilters=false,因为@ComponentScan默认扫描@Component,@Repository,@Service,@Controller等注解

@ComponentScan(value = "com.java", useDefaultFilters=false,
 includeFilters={ @ComponentScan.Filter(type = FilterType.ANNOTATION, 
classes={Controller.class} )

Filter的type类型:

FilterType.ASSIGNABLE_TYPE 可以指定类类型

@ComponentScan(basePackages = {"main.java.com.myAnnotation"}, 
includeFilters = { @ComponentScan.Filter(type= FilterType.ASSIGNABLE_TYPE, 
    classes = {AliController.class}) }, 
useDefaultFilters = false)

FilterType.CUSTOM 可以自定义类型,将AliFilter中满足条件的Bean注入到容器中

@ComponentScan( basePackages = {"main.java.com.myAnnotation"}, 
includeFilters = { @ComponentScan.Filter(type=FilterType.CUSTOM,
     classes = {AliFilter.class}) }, 
useDefaultFilters = false )

 

public class AliFilter implements TypeFilter { 
@Override 
public boolean match(MetadataReader metadataReader, MetadataReaderFactory metadataReaderFactory) throws IOException { 

    ClassMetadata classMetadata = metadataReader.getClassMetadata();             
     
 if(classMetadata.getClassName().equals("main.java.com.myAnnotation.service.CustomService") 
    {         
         return true; 
    } 
 return false;
 } 
}

4.@ComponentScans

配置多个@ComponentScan规则

@ComponentScans( 
value= { 
  @ComponentScan(value = "com.java",
      useDefaultFilters=false, 
      includeFilters={ @ComponentScan.Filter(type = FilterType.ANNOTATION,
      classes={Controller.class} ) }) 
} 

)

 

5.@Scope 决定Bean创建实例的方式

属性:

scopeName 同 value:

singleton: 单实例的(默认),容器启动时就会注入到容器中,立即加载

prototype:多实例的,只有当每次调用/获取的时候才会注入到容器中,延迟加载

request: 每次request请求都会生成一个实例

session:每一个session生成一个实例

@Scope(scopeName = "prototype") 
@Bean 
public Java java(){

 

6.@Lazy 在单实例的情况下,决定实例是否延迟加载

当容器启动时,不会立即注入到容器中,只有当从容器获取的时候才会出入到容器中.

@Lazy 
@Scope(scopeName = "singleton") 
@Bean
public Java java(){

 

7.@Conditional 被标有该注解的类/方法,只有满足条件才回注入/执行

@Conditional({MyCondition.class}) 
@Bean 
public Java java(){

 

public class MyCondition implements Condition{ 
@Override 
public boolean matches(ConditionContext context, AnnotatedTypeMetadata metadata) { 

    Environment environment = context.getEnvironment(); 
   if("Windows 7".equals(environment.getProperty("os.name"))){
       return true; 
   } 
 return false; 
 } 
}

 

8.@Import 直接向容器中注入组件

1)直接注入bean,beanId 为 全路径名

@Configuration
@Import(C.class) 
public class MyConfig {

beanId为: main.java.com.myAnnotation.entity.C

2)通过ImportSelector注入bean,beanId为全路径名

@Configuration 
@Import({MyImportSelector.class}) 
public class MyConfig {

 

public class MyImportSelector implements ImportSelector {
 @Override 
 public String[] selectImports(AnnotationMetadata importingClassMetadata) {
     return new String[]{"com.java.entity.C"}; 
 }
}

3)通过ImportBeanDefinitionRegistrar注入bean,自定义beanId

@Configuration 
@Import({MyImportBeanDefinitionRegistrar.class}) 
public class MyConfig {


 

public class MyImportBeanDefinitionRegistrar implements ImportBeanDefinitionRegistrar { 
 
 @Override public void registerBeanDefinitions(AnnotationMetadata importingClassMetadata, BeanDefinitionRegistry registry) { 
    BeanDefinition beanDefinition = new RootBeanDefinition(Java.class); 
    registry.registerBeanDefinition("java", beanDefinition); //自定义beanId为java
 } 
}

9.通过FactoryBean向容器注入bean

@Bean 
public HtmlFactoryBean htmlFactoryBean(){ 
  return new HtmlFactoryBean(); 
}

 

public class HtmlFactoryBean implements FactoryBean<Html> { 
    @Override 
    public Html getObject() throws Exception { 
      return new Html();
    } 
    @Override
    public Class<?> getObjectType() { 
      return Html.class;
    } 
    @Override 
    public boolean isSingleton() {
       return true; //默认是单例
    } 
}

applicationContext.getBean("htmlFactoryBean"),返回的是Html的实例;如果需要返回HtmlFactoryBean的实例,可以使用applicatioinContext.getBean("&htmlFactoryBean");

 

10.bean生命周期之initMethod,destroyMethod

@Bean(initMethod = "initMethod", destroyMethod = "destroyMethod") 
public C c(){

调用顺序: 构造函数->initMethod->destroyMethod

 

11.bean生命周期之InitializingBean,DisposableBean

public class Html implements InitializingBean, DisposableBean{ 

    public Html(){ 
        System.out.println("html constructor start..."); 
    } 
    @Override 
    public void destroy() throws Exception { 
        System.out.println("html destroy start...."); 
    }
    @Override 
    public void afterPropertiesSet() throws Exception {
         System.out.println("html afterPropertiesSet start..."); 
    } 
}

调用顺序 构造函数->afterPropertiesSet->destroy

 

12.bean生命周期之@PostConstruct,@PreDestroy

public class Html implements {
    public Html(){ 
        System.out.println("html constructor start..."); 
    } 
    @PostConstruct 
    public void postConstruct(){ 
        System.out.println("postConstruct start...."); 
    } 
    @PreDestroy 
    public void preDestroy(){ 
        System.out.println("preDestroy start....");
    } 
}

调用顺序: 构造函数->postConstruct->preDestroy

 

13.bean生命周期之BeanPostProcessor,针对所有的bean

public class MyBeanPostProcessor implements BeanPostProcessor { 

    @Override 
    public Object postProcessBeforeInitialization(Object bean, String beanName) throws 
    BeansException {
         System.out.println("postProcessBeforeInitialization start ...");
         return bean; 
    } 
    @Override 
    public Object postProcessAfterInitialization(Object bean, String beanName) throws 
    BeansException { 
        System.out.println("postProcessAfterInitialization start ..."); 
        return bean; 
    }
 }

调用顺序: 构造函数->postProcessBeforeInitialization->postProcessAfterInitialization

BeanPostProcessor底层原理:

通过代码追踪: AbstractAutowireCapableBeanFactory 类有个方法initializeBean,部分代码截图如下:

    Object wrappedBean = bean; 
    if (mbd == null || !mbd.isSynthetic()) { 
        wrappedBean = this.applyBeanPostProcessorsBeforeInitialization(bean, beanName); // 
 调用BeanPostProcessor的postProcessBeforeInitialization方法 
    } 
    try { 
        this.invokeInitMethods(beanName, wrappedBean, mbd); //调用@PostConstruct,InitializingBean等初始化方法 
    } catch (Throwable var6) {
         throw new BeanCreationException(mbd != null ? mbd.getResourceDescription() : null, 
         beanName, "Invocation of init method failed", var6); 
    } 
    if (mbd == null || !mbd.isSynthetic()) { 
        wrappedBean = this.applyBeanPostProcessorsAfterInitialization(wrappedBean, beanName);//调用BeanPostProcessor的postProcessAfterInitialization方法 
    }

 

14.bean生命周期调用顺序:

构造函数->BeanPostProcessor.postProcessBeforeInitialization->@PostConstruct->InitializingBean.afterPropertiesSet->initMethod->BeanPostProcessor.postProcessAfterInitialization->@PreDestroy->Disposable.destroy->destroyMethod

 

15.@PropertySource

引入外部的properties文件,相当于xml配置中<context:property-placeholder location=""/>

@Configuration 
@PropertySource({"classpath:/JS.properties"}) 
public class MyConfig {

 

16.@Value

给对象属性赋值,相当于xml配置文件中的<property name="" value=""/>

public class Js { 
    @Value("JS入门到精通") //直接赋值 
    private String name; 

    @Value("#{100*0.9}") //通过表达式赋值 
    private Integer price; 

    @Value("${JS.author}") //从配置文件中读取
    private String author;

 

17.@Autowired

默认通过类型获取,如果同类型的有多个实例,则根据属性名称获取;

有required属性,默认true,容器中不存在引用的实例时报错

1)@Autowired放在属性上

public class Jsp { 
@Autowired 
private Js js;

2)@Autowired放在方法上

@Component 
public class Python { 

private Feature feature; 

@Autowired 
public void setFeature(Feature feature) { //从容器中获取feature实例 this.feature = feature; 
}

 

@Bean 
@Autowired 
public Python python(Feature feature){ //从容器中获取feature实例 return new Python(feature); }

3)@Autowired放在构造函数上

@Component 
public class Python { 

private Feature feature;
@Autowired 
public Python(Feature feature) { 
this.feature = feature; 
}

4)@Autowired放在参数上,如果类只有一个带参构造函数,可以不用@Autowired

@Component 
public class Python { 

private Feature feature; 
public Python(@Autowired Feature feature) {
 this.feature = feature; 
}

 

@Bean 
public Python python(Feature feature, C c){ //从容器中获取 
return new Python(feature, c); 
}

16.@Qualifier

与@Autowired连用,引用特定的bean实例

public class Jsp { 
@Qualifier(value="js0") //引用js0
@Autowired 
private Js js;

 

17.@Primary

与@Autowired连用,让spring进行自动装配的时候,默认使用首选的bean

@Primary 
@Bean(name = "js") 
public Js js(){

 

18.@Resource

默认根据名称引入bean实例,可以通过name属性指定名称;

19@Inject

同@Autowired注解,不同的是没有required属性

20.ApplicationContextAware 获取 applicationContext实例

@Component 
public class Company implements ApplicationContextAware{ 
    private ApplicationContext applicationContext; 
    @Override 
    public void setApplicationContext(ApplicationContext applicationContext) throws 
    BeansException { 
        this.applicationContext = applicationContext;
    }

底层原理: 存在一个ApplicationContextAwareProcessor后置处理器,会调用ApplicationContextAware实现类的setApplicationContext方法,其他xxxAware也有对应的后置处理器

 

21.@Profile

针对不同的环境加载不同的配置,默认值为default

@Profile("test")
@Bean public Employee employee(){ 
Employee employee = new Employee(); 
employee.setName("zhangsan"); 
return employee; 
}

@Profile("dev") 
@Bean public Employee employee1(){ 
Employee employee = new Employee(); 
employee.setName("lisi"); 
return employee; 
}

激活Profile

AnnotationConfigApplicationContext applicationContext = new AnnotationConfigApplicationContext();
 
applicationContext.getEnvironment().setActiveProfiles("test"); //在环境启动前 配置profile属性 

applicationContext. register(MyConfig.class);

applicationContext.refresh();

//得用无参构造函数, new AnnotationConfigApplicationContext(MyConfig.class); 会直接执行

//applicationContext.register(MyConfig.class);

//applicationContext.refresh();

 

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值