注解配置spring
1、为什么使用注解配置Spring
基于注解配置的方式也已经逐渐代替xml。这个是不可逆的潮流,所以我们必须要掌握使用注解的方式配置Spring
总结:
(1)使用注解配置Spring,注解的作用就是用于替代XML配置文件的。
(2)XML配置文件,非编程语言语法,所以无法调试
(3)使用注解配置的代码,更加容易定位问题
2、注解配置步骤
第一步:在基于注解的配置中,我们还要多拷贝一个aop的jar包
第二步:在类的根路径下创建一个任意名称的xml文件(不能是中文)
第三步:创建一个测试的服务类,并且加入使用@Component注解,声明该类允许注入到Spring容器
第四步:在spring的配置文件加入扫描注解
组件扫描标签:扫描指定的包的组件类,就会将这些加了组件注解的类创建对象放在容器里面,cn.ong为要扫描的包名
<context:component-scan base-package="cn.ong"></context:component-scan>
第五步:测试调用代码
3、Spring常用注解说明
(1)用于对象的注解:将用于被扫描创建对象的注解,统称为组件注解。
组件注解包括:@Component,@Controller,@Service,@Repository,功能上没有任何区别,只是概念上不一样,组件在spring-context-4.2.9.RELEASE.jar包里面的org.springframework.stereotype包下
(2)Spring第一版注解的实现(spring 2.5),就是使用一个@Component。从3.0以后,根据分层的需要,把它拆成了四个。为了可以让开发人员,可见即可得,一看到注解,立即知道类的性质所以分成了四个
@Controller:用于声明表示层的组件注解
@Service:用于声明服务层的组件注解
@Repository:用于声明持久层的组件注解
@Component:用于声明三层以外的组件注解
4、用于依赖注入的注解
(1)@Autowired注解:用于给引用注入容器的对象。
属性 required:指定注入的对象是否允许为空,如果required=true。表示不可以为空,会报异常
(2)使用@Autowired注入的三种情况
放在属性上注入
放在方法上注入
放在构造方法上注入
(3)@Qualifier注解:用于强制指定注入的对象名,使用@Autowired注入对象时,@Autowired没有指定对象名的属性,只能通过@Qualifier字段容器中对象名
属性value:指定注入Spring容器中对应对象名的对象给引用。
@Qualifier(value="指定的名字")
(4)@Resource注解:用于给引用注入容器的对象,可以通过name属性指定对象名
@Resource(name="指定的名字")
注意事项:@Resource只能注入方法和属性,不能注入构造方法
(5)通过查看注解的声明,理解注解可以存放的位置以及有哪些属性,要学会通过注解声明的@Target的类型类来分析,注解可以放的位置
(6)@value 注解:value只能设置(基础数据类型+包装类+String)
@Value注解:注入基本数据类型以及它们的包装类和String类型数据的,支持${}注入Properties文件的键值对,等同 <proprty name=”...” value=”${Key}”>
例如配置在属性上:
@Value("张三")
private String name;
@Value("20")
private int age;
@Autowired
@Qualifier("now")
private Date createDate;
例如配置在构造方法上:
public CustomerService(@Value("张三")String naem, @Value("20")int age,@Autowired @Qualifier("now") Date createDate) {
super();
this.naem = naem;
this.age = age;
this.createDate = createDate;
}
注入其他类型的时候,可以先注入@Autowired,然后注入@Qualifier("now"),强制指定输入的值,now为在xml配置文件上配置的java类 <bean name="now" class="java.util.Date"></bean>
(7)@Scope 注解来指定对象的生命周期的,取值为:singleton prototype request session
@Scope("singleton")设置为单例,或者设置为:@Scope(value=BeanDefinition.SCOPE_PROTOTYPE)
对象出生:当程序加载配置文件创建容器时,创建
对象活着:只要容器还在,一直活着
对象死亡:应用停止,容器销毁,对象死亡
@Scope("singleton")设置为多例(原型对象)
对象出生:当程序加载配置文件创建容器时创建对象
对象活着:只要对象被使用,一直活着
对象死亡:对象长时间不用,会被Java垃圾回收机制回收
*reqeust:web项目中,Spring将创建的对象放在request作用域中
*session:web项目中,Spring将创建的对象放在session作用域中
(8)@PostConstruct :等同于<bean init-method=””>
作用:用于指定初始化方法。
(9)@PreDestroy:等同于<bean destory-method=””>
作用:用于指定销毁方法。
5、纯注解配置 @Configuration
第一步:添加@Configuration在配置类ApplicationContextConfig上,声明该类是配置类,加上@Configuration,xml配置文件可以不需要再配置
第二步:添加@ComponentScan(basePackages="cn.ong") 在配置类ApplicationContextConfig上,配置扫描的包
第三步:编写测试类,创建配置文件类创建容器 AnnotationConfigApplicationContext context = new AnnotationConfigApplicationContext(ApplicationContextConfig.class);
第四步:拿到容器中的对象 context.getbean("默认的类名",类.class),使用该对象
6、注解说明
(1)@Configuration 配置类注解,在纯注解配置中,加了该注解就意味着该类是Spring的配置类。该类的功能就是用于替代原来的XML配置文件。
使用: 获取容器时需要使用AnnotationConfigApplicationContext(有@Configuration注解的类.class)。
(2)@ComponentScan注解类,作用就是配置扫描Spring组件类的路径。作用和在spring的xml配置文件中的:
<context:component-scan base-package="com.sxt"/>是一样的。
属性: basePackages:用于指定要扫描的包。和该注解中的value属性作用一样。
(3)@PropertySource注解 用于加载 .properties文件中的配置。例如我们配置数据源时,可以把连接数据库的信息写到properties配置文件中,就可以使用此注解指定properties配置文件的位置。
属性:encoding:编码格式
value[]:用于指定properties文件位置。如果是在类路径下,需要写上classpath:
例如:@PropertySource(encoding="utf-8",value="customer.properties")
@PropertySource注解,因为4.2版本的Spring容器初始化的时候,没有默认创建PropertySourcesPlaceholderConfigurer对象。需要手工创建一个静态方法来或者该对象,静态的方法会在创建容器之前创建该对象,用于读取@PropertySource的值。所以方法必须要静态
例如:
@Bean
public static PropertySourcesPlaceholderConfigurer getPropertySourcesPlaceholderConfigurer(){
return new PropertySourcesPlaceholderConfigurer();
}
(4)@Bean注解 该注解只能写在方法上,使用此方法创建一个对象,并且放入spring容器。它就相当于我们之前在xml配置中介绍的<bean标签>
属性name:给当前@Bean注解方法创建的对象指定一个名称(即bean的id)。
(5)@Import注解 用于导入其他配置类,在引入其他配置类时,可以不用再写@Configuration注解
属性: value[]:用于指定其他配置类的字节码。
例如:@Import(value=Text.class)
7、JUnti:是一个单元测试框架,所谓的单元测试就是可以对单个方法测试
JUnti 就是main,一个类只能写一个main方法,而JUnti框架可以在一个类里面写的多个方法
(1)使用:在类上加上 @Test ,然后倒入JUnti类库
(2)属性: @Test (timeout=1000),测试性能,就是规定时间(1秒)内没有运行完会报错
整合,不需要再手动创建容器:
第一步:在执行JUnti之前,加载SpringJUnit4ClassRunner执行器,把对象放到容器中
@RunWith(value=SpringJUnit4ClassRunner.class)
第二步:配置xml文件 @ContextConfiguration(locations="classpath:applicationContext.xml")
第三步:在测试类中创建属性,通过依赖注入来拿对象,以后就不需要再创建容器,关闭容器
@Autowired
HelloWorldService helloWorldService;
8、注解语法构造
(1) Annotation接口:是所有注解的父类,可以接收所以注解的对象
(2) Documented注解:是一个基础注解,用于声明注解是支持生成javadoc文档的注释
(3)ElementType枚举:是一个注解可以放在的位置的类型。
(4) Inherited注解:是一个基础注解,用于声明注解在使用可以支持被子类继承
(5) Retention注解:用于指定注解撤策略,这个注解是使用什么策略的
(6) RetentionPolicy枚举:注解的策略类型
CLASS:编译后还在字节码里面,但运行的时候,忽略,很少用,因为不支持反射读取
RUNTIME:支持反射读取,最常用
SOURCE:编译后的代码就不存在这个注解了,(看一下)
9、注解入门
第一步:创建注解
第二步:配置注解类
@Target(value = { ElementType.FIELD, ElementType.METHOD }) //指定注解只能放在或属性上
@Retention(RetentionPolicy.RUNTIME) //设置注解能被反射技术读取
@Documented //支持生成javadoc
public @interface Value {
String value() default "";
}
第三步:声明一个类,使用该注解依赖注入
@Value("zhangsan")
public String name;
public String getName() {
return name;
}
第四步:编写测试类
@Test
public void test() throws Exception {
UserAction userAction = new UserAction();
//通过反射技术对value注解进行解释,让它具有将值赋予给属性的字段
Class<UserAction> userActionClass = UserAction.class;
Field field = userActionClass.getField("name"); //获得该类的属性
Value value = (Value) field.getDeclaredAnnotations()[0]; //获得该注解的注解
if (value != null) {
field.setAccessible(true); // 将私有的属性设置为可访问的
field.set(userAction, value.value()); //设置
}
System.err.println(userAction.getName());
}