前言
spring是我们web开发中必不可少的一个框架,基于传统的xml方式配置bean总觉得太过繁琐,从spring2.5之后注解的出现可以大大简化我们的配置。
入门的注解开发
@Configuration用于定义配置类,可替换xml配置文件,被注解的类内部包含有一个或多个被@Bean注解的方法,这些方法将会被AnnotationConfigApplicationContext或AnnotationConfigWebApplicationContext类进行扫描,并用于构建bean定义,初始化Spring容器。
下面我们来验证一下,首先创建配置类。
package test;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
/**
* spring容器
* Description:
* @author liuyc
* @date 2019年4月6日
* Copyright (C); 2019
*/
@Configuration
public class SpringContainer {
public SpringContainer() {
System.out.println("spring容器初始化完成!");
}
/**
* @Bean注解作用是告诉spring容器这个方法会返回一个bean,并且这个bean交给
* spring容器管理
* @return
*/
@Bean
public Human getInstance(){
return new Human();
}
}
其次是Human类。
package test;
public class Human {
public Human(){
System.out.println("Hello World!");
}
}
最后我们来测试一下。
package test;
import org.springframework.context.ApplicationContext;
import org.springframework.context.annotation.AnnotationConfigApplicationContext;
/**
* 测试spring注解
* Description:
* @author liuyc
* @date 2019年4月6日
* Copyright (C); 2019
*/
@SuppressWarnings("all")
public class TestSpring {
public static void main(String[] args) {
ApplicationContext ctx = new AnnotationConfigApplicationContext(SpringContainer.class);
/**
* 当@Bean注解没有指定bean的id的时候,需要
* 根据生成bean的方法名获取bean实例,此处在SpringContainer类中的方法是getInstance
*/
Human hu = ctx.getBean("getInstance",Human.class);
}
}
执行结果:
log4j:WARN No appenders could be found for logger (org.springframework.core.env.StandardEnvironment).
log4j:WARN Please initialize the log4j system properly.
log4j:WARN See http://logging.apache.org/log4j/1.2/faq.html#noconfig for more info.
spring容器初始化完成!
Hello World!
这里没有设置懒加载,所以在初始化spring容器的时候,Human已经实例化了,并且默认是单例模式。
指定@Bean注解的bean的Id,作下稍微的修改。
package test;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
/**
* spring容器
* Description:
* @author liuyc
* @date 2019年4月6日
* Copyright (C); 2019
*/
@Configuration
public class SpringContainer {
public SpringContainer() {
System.out.println("spring容器初始化完成!");
}
/**
* @Bean注解作用是告诉spring容器这个方法会返回一个bean,并且这个bean交给
* spring容器管理
* @return
*/
@Bean(name="human")
public Human getInstance(){
return new Human();
}
}
package test;
import org.springframework.context.ApplicationContext;
import org.springframework.context.annotation.AnnotationConfigApplicationContext;
/**
* 测试spring注解
* Description:
* @author liuyc
* @date 2019年4月6日
* Copyright (C); 2019
*/
@SuppressWarnings("all")
public class TestSpring {
public static void main(String[] args) {
ApplicationContext ctx = new AnnotationConfigApplicationContext(SpringContainer.class);
/**
* 当@Bean注解没有指定bean的id的时候,需要
* 根据生成bean的方法名获取bean实例,此处在SpringContainer类中的方法是getInstance
*/
Human hu = ctx.getBean("human",Human.class);
}
}
测试结果也是跟上面一样,所以是行得通的。
结合@ComponentScan、@Component注解实例化bean
上面的例子完全是根据概念来的,实验证明是可行的。但是如果bean的数量太多的话,那么每个bean一个对应的生成方法,那也是一个不小的工作量,且非常不便利。所以开启组件扫描可以大大简化开发的工作量。
首先,需要改造一下配置类,这里就不需要使用bean注解了:
package test;
import org.springframework.context.annotation.ComponentScan;
import org.springframework.context.annotation.Configuration;
/**
* spring容器
* Description: @ComponentScan开启组件扫描,指定包路径下的带有组件注解的类都会
* 被spring容器实例化
* @author liuyc
* @date 2019年4月6日
* Copyright (C); 2019
*/
@Configuration
@ComponentScan("test")
public class SpringContainer {
public SpringContainer() {
System.out.println("spring容器初始化完成!");
}
}
其次,在Human类添加@Component注解:
package test;
import org.springframework.stereotype.Component;
/**
* 实体类
* Description: @Component注解会告诉spring容器这个类是一个组件,需要spring管理并实例化
* @author liuyc
* @date 2019年4月6日
* Copyright (C); 2019 Powersi
*/
@Component
public class Human {
public Human(){
System.out.println("Hello World!");
}
}
测试类不需要修改,执行结果跟之前一样。
注解进阶开发
前面讲了bean的实例化,下面我们开始讲讲如何给bean注入属性,就是我们常说的自动装配。先来讲讲@Autowired注解的用法,@Autowired可以对类成员变量、方法及构造函数进行标注,完成自动装配的工作。
package test;
import org.springframework.context.annotation.ComponentScan;
import org.springframework.context.annotation.Configuration;
/**
* spring容器
* Description: @ComponentScan开启组件扫描,指定包路径下的带有组件注解的类都会
* 被spring容器实例化
* @author liuyc
* @date 2019年4月6日
* Copyright (C); 2019
*/
@Configuration
@ComponentScan("test")
public class SpringContainer {
public SpringContainer() {
System.out.println("spring容器初始化完成!");
}
}
package test;
import org.springframework.stereotype.Component;
@Component
public class Car {
public Car() {
System.out.println("Car类实例化完成!");
}
}
package test;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.context.annotation.Lazy;
import org.springframework.stereotype.Component;
/**
* 实体类
* Description: @Component注解会告诉spring容器这个类是一个组件,需要spring管理并实例化
* @Lazy注解告诉spring该bean实例化实行懒加载
* @author liuyc
* @date 2019年4月6日
* Copyright (C); 2019 Powersi
*/
@Component
@SuppressWarnings("all")
@Lazy
public class Human {
/** audi属性即使没有set方法,
* @Autowired注解也可以将其注入 */
@Autowired
private Car audi;
private Car bmw;
private Car benz;
public Human(){
System.out.println("Human类实例化完成!");
}
/**
* @Autowired注解使用在set方法,注入属性
* @param bmw
*/
@Autowired
public void setBmw(Car bmw) {
this.bmw = bmw;
}
@Autowired
public void setBenz(Car benz) {
this.benz = benz;
}
public Car getAudi() {
return audi;
}
public Car getBmw() {
return bmw;
}
public Car getBenz() {
return benz;
}
}
package test;
import org.springframework.context.ApplicationContext;
import org.springframework.context.annotation.AnnotationConfigApplicationContext;
/**
* 测试spring注解
* Description:
* @author liuyc
* @date 2019年4月6日
* Copyright (C); 2019
*/
@SuppressWarnings("all")
public class TestSpring {
public static void main(String[] args) {
ApplicationContext ctx = new AnnotationConfigApplicationContext(SpringContainer.class);
/**
* 当@Bean注解没有指定bean的id的时候,需要
* 根据生成bean的方法名获取bean实例,此处在SpringContainer类中的方法是getInstance
*/
Human hu = ctx.getBean("human",Human.class);
System.out.println("奥迪:"+hu.getAudi());
System.out.println("宝马:"+hu.getBmw());
System.out.println("奔驰:"+hu.getBenz());
}
}
测试结果如下:
log4j:WARN No appenders could be found for logger (org.springframework.core.env.StandardEnvironment).
log4j:WARN Please initialize the log4j system properly.
log4j:WARN See http://logging.apache.org/log4j/1.2/faq.html#noconfig for more info.
spring容器初始化完成!
Car类实例化完成!
Human类实例化完成!
奥迪:test.Car@1e9029b
宝马:test.Car@1e9029b
奔驰:test.Car@1e9029b
Human类加了@Lazy注解,所以在spring容器初始化的时候并没有实例化。
还有其它问题:@Autowired和@Resource区别、注解如何实现自定义作用域、如何注入List、Map;String、Integer如何注入。。。待续