spring基于注解的开发

前言

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如何注入。。。待续 

 

 

 

你可能感兴趣的:(Spring)