java开启注解驱动怎么做_Spring注解驱动开发

1. @Configuration和@Bean注解

/**

* 配置类等同之前的applicationContext.xml配置文件

*/

@Configuration //告诉spring这是一个配置类

public class MainConfig {

/**

* 使用注解在容器中注册bean,默认id是方法名,返回值为bean的类型

*

* @Bean的vale值可以指定生成bean的id

*/

@Bean(value = "person1")

public Person person() {

return new Person("ghw", 20);

}

}

2. @ComponentScan 包扫描

排除指定的类-Controller.class, Service.class

@ComponentScan(value = "com.ghw.springannotation", excludeFilters = {

@ComponentScan.Filter(type = FilterType.ANNOTATION, classes = {Controller.class, Service.class})

})

public class MainConfig {

//省略

}

运行结果如图:

184342940008

image.png

只包含指定的类 (因为useDefaultFilters 默认是true会扫描所有的类,所以要先改为false)

@ComponentScan(value = "com.ghw.springannotation", includeFilters = {

@ComponentScan.Filter(type = FilterType.ANNOTATION, classes = {Controller.class})

}, useDefaultFilters = false)

public class MainConfig {

/**

* 使用注解在容器中注册bean,默认id是方法名,返回值为bean的类型

*

* @Bean的vale值可以指定生成bean的id

*/

@Bean(value = "person1")

public Person person() {

return new Person("ghw", 20);

}

}

运行结果如图:

184342940008

image.png

FilterType有多种,ANNOTATION是按照注解选择,ASSIGNABLE_TYPE是按照类型选择,@REGEX是正则表达式,@ASPECTJ是使用ASPECTJ注解,@CUSTOM是使用自定义规则

public enum FilterType {

ANNOTATION,

ASSIGNABLE_TYPE,

ASPECTJ,

REGEX,

CUSTOM;

private FilterType() {

}

}

3.@Scope @Lazy

public class MainConfig {

/**

* 使用注解在容器中注册bean,默认id是方法名,返回值为bean的类型

*

* @Bean的vale值可以指定生成bean的id

* @Scope value可取

* singleton,单实例,默认值,ioc容器启动即创建对象并放入容器

* prototype,多实例,使用的时候才去创建对象放入容器

* request,同一次请求创建一个request

* session,同一次请求创建一个session

*/

@Scope(value = "prototype")

@Lazy //懒加载,单实例的时候使用,使用的时候才去创建对象

@Bean(value = "person1")

public Person person() {

System.out.println("调用此方法");

return new Person("ghw", 20);

}

}

4. @Conditional

按照条件注册bean

创建俩个Bean

/**

* Conditional也可以放在类上,表示所有类都生效

* @return

*/

@Conditional({WindowsCondition.class})

@Bean(value = "windows")

public Person person01() {

return new Person("windows", 20);

}

@Conditional({LinuxCondition.class})

@Bean(value = "linux")

public Person person02() {

return new Person("linux", 20);

}

创建俩个Condition

LinuxCondition

package com.ghw.springannotation.condition;

import org.springframework.context.annotation.Condition;

import org.springframework.context.annotation.ConditionContext;

import org.springframework.core.env.Environment;

import org.springframework.core.type.AnnotatedTypeMetadata;

public class LinuxCondition implements Condition {

/**

* ConditionContext:判断条件使用的上下文环境

* AnnotatedTypeMetadata:注释信息

*/

@Override

public boolean matches(ConditionContext conditionContext, AnnotatedTypeMetadata annotatedTypeMetadata) {

Environment environment = conditionContext.getEnvironment();

String osname = environment.getProperty("os.name");

if (osname.contains("Linux")) {

return true;

}

return false;

}

}

WindowsCondition

package com.ghw.springannotation.condition;

import org.springframework.context.annotation.Condition;

import org.springframework.context.annotation.ConditionContext;

import org.springframework.core.env.Environment;

import org.springframework.core.type.AnnotatedTypeMetadata;

/**

* 判断是否windows系统

*/

public class WindowsCondition implements Condition {

/**

* ConditionContext:判断条件使用的上下文环境

* AnnotatedTypeMetadata:注释信息

*/

@Override

public boolean matches(ConditionContext conditionContext, AnnotatedTypeMetadata annotatedTypeMetadata) {

Environment environment = conditionContext.getEnvironment();

String osname = environment.getProperty("os.name");

if (osname.contains("Windows")) {

return true;

}

return false;

}

}

5. @Import

总结:

给容器中注册组件:

@Controller @Service @Component @Repository 自己创建的类

@Bean 第三方jar包内组件

@Import 快速给容器中导入一个组件

在类名上面加@Import

@Import({Red.class, Green.class})

public class MainConfig {

结果如下,默认bean是全类名

信息: Refreshing org.springframework.context.annotation.AnnotationConfigApplicationContext@763d9750: startup date [Sat Aug 25 23:11:04 CST 2018]; root of context hierarchy

bean name:org.springframework.context.annotation.internalConfigurationAnnotationProcessor

bean name:org.springframework.context.annotation.internalAutowiredAnnotationProcessor

bean name:org.springframework.context.annotation.internalRequiredAnnotationProcessor

bean name:org.springframework.context.annotation.internalCommonAnnotationProcessor

bean name:org.springframework.context.event.internalEventListenerProcessor

bean name:org.springframework.context.event.internalEventListenerFactory

bean name:mainConfig

bean name:bookController

bean name:com.ghw.springannotation.importt.Red

bean name:com.ghw.springannotation.importt.Green

bean name:person1

bean name:linux

os name:Linux

Process finished with exit code 0

@ImportSelector

自定义要导入的bean类型,实现ImportSelector接口,实现方法selectImports,返回一个字符串数组,内容是要导入bean的全路径,annotationMetadata参数可以获取容器注解全部信息

package com.ghw.springannotation.importt;

import org.springframework.context.annotation.ImportSelector;

import org.springframework.core.type.AnnotationMetadata;

public class MyImportSelect implements ImportSelector {

@Override

public String[] selectImports(AnnotationMetadata annotationMetadata) {

return new String[]{"com.ghw.springannotation.importt.Blue"};

}

}

184342940008

annotationMetadata中的内容

@ImportBeanDefinitionRegistrar

实现ImportBeanDefinitionRegistrar 接口,通过参数beanDefinitionRegistry的containsBeanDefinition方法判断当前容器中是否包含某个bean,然后通过registerBeanDefinition方法注册新的bean

package com.ghw.springannotation.importt;

import org.springframework.beans.factory.support.BeanDefinitionRegistry;

import org.springframework.beans.factory.support.RootBeanDefinition;

import org.springframework.context.annotation.ImportBeanDefinitionRegistrar;

import org.springframework.core.type.AnnotationMetadata;

public class MyImportBeanDefinitionRegistrar implements ImportBeanDefinitionRegistrar {

@Override

public void registerBeanDefinitions(AnnotationMetadata annotationMetadata, BeanDefinitionRegistry beanDefinitionRegistry) {

Boolean red = beanDefinitionRegistry.containsBeanDefinition("com.ghw.springannotation.importt.Red");

Boolean green = beanDefinitionRegistry.containsBeanDefinition("com.ghw.springannotation.importt.Green");

if (red && green) {

RootBeanDefinition beanDefinition = new RootBeanDefinition(RainBow.class);

beanDefinitionRegistry.registerBeanDefinition("rainbow", beanDefinition);

}

}

}

@Import({Red.class, Green.class, MyImportSelect.class, MyImportBeanDefinitionRegistrar.class})

public class MainConfig {

6. @FactoryBean

通过工厂Bean创建对象

package com.ghw.springannotation.factory;

import com.ghw.springannotation.importt.Color;

import org.springframework.beans.factory.FactoryBean;

/**

* Color类的工厂Bean,工厂Bean创建Color类,返回color对象,加入容器

*/

public class ColorFactoryBean implements FactoryBean {

@Override

public Color getObject() throws Exception {

System.out.println("调用getObject方法返回Color对象");

return new Color();

}

@Override

public Class> getObjectType() {

return Color.class;

}

@Override

/**

* true 单例

* false 多例

*/

public boolean isSingleton() {

return false;

}

}

在Config类中加入ColorFactoryBean的注解

@Bean

public ColorFactoryBean ColorFactoryBean() {

return new ColorFactoryBean();

}

测试方法

@Test

public void test() throws Exception {

printBeans(context);

Object bean = context.getBean("ColorFactoryBean");

Object bean2 = context.getBean("ColorFactoryBean");

Color color = (Color) bean;

System.out.println(bean == bean2);

color.print();

//取得当前环境

ConfigurableEnvironment environment = context.getEnvironment();

System.out.println("os name:" + environment.getProperty("os.name"));

}

public void printBeans(AnnotationConfigApplicationContext context) {

String[] nameForType = context.getBeanDefinitionNames();

//遍历输出注册的bean

for (String s : nameForType) {

System.out.println("bean name:" + s);

}

}

总结:

184342940008

image.png

7. initMethod和destroyMethod

首先定义Car类,并编写构造方法init方法和destory方法

package com.ghw.springannotation.bean;

/**

* Bean的init和destory方法

*/

public class Car {

public Car() {

System.out.println("Car构造方法执行");

}

public void init() {

System.out.println("Car初始化方法");

}

public void destory() {

System.out.println("Car销毁方法");

}

}

在MainConfig类中添加注解,在注解上添加initMethod,destroyMethod

@Bean(initMethod = "init",destroyMethod = "destory")

public Car car() {

return new Car();

}

public void test02() {

Car car = (Car) context.getBean("car");

System.out.println(car);

context.close();

}

输出结果如下

信息: Refreshing org.springframework.context.annotation.AnnotationConfigApplicationContext@6f79caec: startup date [Sun Aug 26 23:19:52 CST 2018]; root of context hierarchy

Car构造方法执行

Car初始化方法

八月 26, 2018 11:19:52 下午 org.springframework.context.support.AbstractApplicationContext doClose

信息: Closing org.springframework.context.annotation.AnnotationConfigApplicationContext@6f79caec: startup date [Sun Aug 26 23:19:52 CST 2018]; root of context hierarchy

enter test02

com.ghw.springannotation.bean.Car@49d904ec

Car销毁方法

从结果可以看出容器创建的时候就执行构造方法然后执行init方法,容器关闭之后才执行test02,destory方法。此处有疑惑,正常不应该是先执行test再关闭容器。

以上是单实例的情况,如果是多实例,则会在使用bean的时候执行构造方法和初始化方法,容器关闭也不会执行销毁方法

如下图:

八月 26, 2018 11:22:27 下午 org.springframework.context.support.AbstractApplicationContext prepareRefresh

信息: Refreshing org.springframework.context.annotation.AnnotationConfigApplicationContext@6f79caec: startup date [Sun Aug 26 23:22:27 CST 2018]; root of context hierarchy

八月 26, 2018 11:22:28 下午 org.springframework.context.support.AbstractApplicationContext doClose

信息: Closing org.springframework.context.annotation.AnnotationConfigApplicationContext@6f79caec: startup date [Sun Aug 26 23:22:27 CST 2018]; root of context hierarchy

enter test02

Car构造方法执行

Car初始化方法

com.ghw.springannotation.bean.Car@4b5d6a01

7. InitializingBean, DisposableBean接口

功能和#6相似

package com.ghw.springannotation.bean;

import org.springframework.beans.factory.DisposableBean;

import org.springframework.beans.factory.InitializingBean;

import org.springframework.stereotype.Component;

/**

* 测试InitializingBean和DisposableBean接口

*/

@Component

public class Cat implements InitializingBean, DisposableBean {

public Cat() {

System.out.println("Cat执行构造方法");

}

@Override

public void destroy() throws Exception {

System.out.println("Cat销毁方法");

}

@Override

public void afterPropertiesSet() throws Exception {

System.out.println("Cat初始化方法");

}

}

test方法

package com.ghw.springannotation.bean;

import com.ghw.springannotation.MainConfig;

import org.junit.Test;

import org.springframework.context.annotation.AnnotationConfigApplicationContext;

public class CatTest {

//获取context

AnnotationConfigApplicationContext context = new AnnotationConfigApplicationContext(MainConfig.class);

@Test

public void test() {

context.getBean("cat");

context.close();

}

}

结果如下:

八月 26, 2018 11:36:14 下午 org.springframework.context.support.AbstractApplicationContext prepareRefresh

信息: Refreshing org.springframework.context.annotation.AnnotationConfigApplicationContext@67117f44: startup date [Sun Aug 26 23:36:14 CST 2018]; root of context hierarchy

Cat执行构造方法

Cat初始化方法

八月 26, 2018 11:36:14 下午 org.springframework.context.support.AbstractApplicationContext doClose

信息: Closing org.springframework.context.annotation.AnnotationConfigApplicationContext@67117f44: startup date [Sun Aug 26 23:36:14 CST 2018]; root of context hierarchy

Cat销毁方法

8. @PostConstruct和@PreDestory

这俩个注解是JSR250中提出的

新建Dog类做测试

package com.ghw.springannotation.bean;

import org.springframework.stereotype.Component;

import javax.annotation.PostConstruct;

import javax.annotation.PreDestroy;

/**

* 测试@PostConstruct和@PreDestory

*/

@Component

public class Dog {

public Dog() {

System.out.println("Dog构造方法执行");

}

/**

* PostConstruct注解的方法在Bean创建完成并且属性赋值之后执行

*/

@PostConstruct

public void init() {

System.out.println("Dog初始化方法");

}

/**

* PreDestroy注解的方法在容器销毁Bean之前执行

*/

@PreDestroy

public void destory() {

System.out.println("Dog销毁方法");

}

}

DogTest.java

package com.ghw.springannotation.bean;

import com.ghw.springannotation.MainConfig;

import org.junit.Test;

import org.springframework.context.annotation.AnnotationConfigApplicationContext;

import static org.junit.Assert.*;

public class DogTest {

//获取context

AnnotationConfigApplicationContext context = new AnnotationConfigApplicationContext(MainConfig.class);

@Test

public void test() {

context.getBean("dog");

context.close();

}

}

运行结果如下:

184342940008

image.png

9. BeanPostProcessor接口,Bean的后置处理器

postProcessBeforeInitialization在初始化之前执行

postProcessAfterInitialization在初始化之后执行

package com.ghw.springannotation.bean;

import org.springframework.beans.BeansException;

import org.springframework.beans.factory.config.BeanPostProcessor;

import org.springframework.stereotype.Component;

/**

* @author gaoho

*/

@Component

public class MyBeanPostProcessor implements BeanPostProcessor {

public Object postProcessBeforeInitialization(Object bean, String beanName) throws BeansException {

System.out.println("beanName:" + beanName + "bean:" + bean + "Before");

return bean;

}

public Object postProcessAfterInitialization(Object bean, String beanName) throws BeansException {

System.out.println("beanName:" + beanName + "bean:" + bean + "After");

return bean;

}

}

执行结果如下:

beanName:dogbean:com.ghw.springannotation.bean.Dog@4e91d63f---Before

beanName:dogbean:com.ghw.springannotation.bean.Dog@4e91d63f---After

BeanPostProcessor原理:

184342940008

image.png

184342940008

image.png

184342940008

image.png

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值