Spring进阶之路(12)-注解方式实现Bean的注入

鉴于之前的博文中都是通过在xml中对bean进行配置的方式注入的,又加上博友的要求,决定对注解方式进行一个简单的讲解,这里不会涉及太复杂的程序,因为本文的目的是让看到这篇博文的广大博友能懂,而不是云里雾里的怎么也看不明白。



常用的注解



1. @Controller:标注一个控制器组件的类。

2. @Service:标注一个业务逻辑组件的类。

3. @Repository:标注一个Dao组件的类。

4. @Component:标注一个普通的类。

这几个注解主要用于标注Spring要进行实例化的类,一旦在某个类的上面标注了这样的注解,如果是单例模式的话,那么Spring在初始化的时候,就会将这些类实例化,而对于非单例模式的类,不取决于Spring容器本身,往往是客户端进行请求的时候,进行创建实例(Spring创建的),这些在之前的博文中已经进行过说明,请参考Spring进阶之路(7)-Bean的生命周期以及创建、销毁执行流程。

5. @Resource:按照名称(name)进行注入。该注解属于jdk中的注解,但是在项目中使用比较广泛。

6. @Autowired:按照类型匹配自动注入。

这里的两个注解主要用于为类中属性注入值。两个注解可以将(上面四个注解标注的类在Spring中实例化后的对象)注入到某些类的属性中。


7. @Scope("prototype"):默认的情况下是产生单例对象,在Scope的里面传了prototype的参数后,表明该类不是单例的,而是"多例的",不知道这么解释标准不标准,读者可以纠正。

8. @PostConstruct:指定bean的初始化方法与之前博文中配置文件指定的initMethod作用相同(Spring进阶之路(7)-Bean的生命周期以及创建、销毁执行流程),Spring会在Bean的依赖注入完成后回调这个方法。

9. @PreDestroy:指定bean的销毁之前的方法与Spring进阶之路(7)-Bean的生命周期以及创建、销毁执行流程这篇博文中配置文件指定的destroyMethod的作用是一样的,他会在bean销毁之前调用。


另外:

10: @Lazy:用于指定该类是否取消预初始化。指定参数boolean型true即可,下面不在赘述,这个注解比较简单。

11: @DependsOn:可以修饰类或者方法,用于强制初始化一些bean,例如:@DependsOn({"wy", "wangyang"}),这样在初始化之前会强制初始化里面的bean.



实例演示


用注解进行自动注入bean的前提是在配置文件中配置了自动注入的支持。



		
		

下面来展示一个简化版的用户登录功能

控制器组件:

用到了@Controller、@Scope、@Resource、@Autowired四个注解,如果这里没有被注入进来的话,会在调用的地方抛出空指针异常,如果不抛出空指针就说明bean已经被注入进来了。

package com.siti.spring20160316;

import javax.annotation.Resource;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.context.annotation.Scope;
import org.springframework.stereotype.Controller;

@Controller
@Scope("prototype")
public class UserAction {

	@Resource
	private UserService userService;
	@Autowired
	private Utils utils;
	
	public boolean login(String userName, String password){
		System.out.println("UserAction--login");
		
		if(utils.check(userName)){
			if(userService.login(userName, password)){
				return true;
			}
		}
		return false;
	}
	
}

Service业务逻辑层

在这里说明下,一般我们开发中比较喜欢用接口,这里是为了看起来清楚没有采用接口的形式,避免读者看的云里雾里搞不清楚流程。

这里主要用到的注解有@Service(标注业务逻辑层)、@PostCustruct(标注的方法相当于initMethod)、@PreDestroy(标注的方法相当于destroyMethod)

package com.siti.spring20160316;

import javax.annotation.PostConstruct;
import javax.annotation.PreDestroy;
import javax.annotation.Resource;

import org.springframework.stereotype.Service;
/**
 * 
 * @ProjectName SpringBlob
 * @ClassName UserService
 * @Description 一般情况下,都是采用接口的,这里没有使用接口,便于读者直接看清楚调用关系
 * @author wy
 * @date 2016-3-16
 *
 */
@Service
public class UserService {

	@Resource
	private UserDao userDao;
	
	public boolean login(String userName, String password){
		System.out.println("UserService--login");
		if(userDao.isExist(userName, password)){
			return true;
		}
		return false;
	}
	
	@PostConstruct
	public void init(){
		System.out.println("UserService--init");
	}
	
	@PreDestroy
	public void destroyMethod(){
		System.out.println("UserService--destroyMethod");
	}
}
DAO层

主要用到的注解有@Repository

由于这里属于模拟没有加入连接数据库部分的持久化操作,请见谅。

package com.siti.spring20160316;

import org.springframework.stereotype.Repository;

@Repository
public class UserDao {

	public boolean isExist(String userName, String password){
		System.out.println("UserDao--isExist");
		if("wy".equals(userName)){
			return true;
		}
		return false;
	}
}

进行测试

第一个输出比较两个得到的对象是不是同一个对象。读者可以自己检验其他的几个对象是不是同一个。因为UserAction类标注了@Scope的注解并指定其类型为prototype,那么这里应该是不一样的,输出false

package com.siti.spring20160316;

import org.springframework.context.support.AbstractApplicationContext;
import org.springframework.context.support.ClassPathXmlApplicationContext;

public class MainTest {

	public static void main(String[] args) {
		AbstractApplicationContext context = new ClassPathXmlApplicationContext("applicationContext20160316.xml");
		UserAction action = (UserAction) context.getBean("userAction");
		UserAction action2 = (UserAction) context.getBean("userAction");
		
		System.out.println("这两个对象是否是同一个对象:" + action.equals(action2));
		
		boolean bool = action.login("wy", "******");
		if(bool){
			System.out.println("登录成功!");
		}else{
			System.out.println("登录不成功!");
		}
		context.registerShutdownHook();
	}
}

输出结果

Spring进阶之路(12)-注解方式实现Bean的注入_第1张图片



自定义注解


这里只是自己写了个注解,但是没有解析类是没办法去用的,读者可以试试看能不能自己写出他的处理类,可以共同交流下。

package com.siti.spring20160316;

import java.lang.annotation.ElementType;
import java.lang.annotation.Retention;
import java.lang.annotation.RetentionPolicy;
import java.lang.annotation.Target;

@Retention(RetentionPolicy.RUNTIME)// 运行期间注入
@Target({ElementType.FIELD, ElementType.METHOD})// 可以标注在哪里,这里是属性和方法上
public @interface MyAutowired {
	// 参数
	public String name() default "";
}


你可能感兴趣的:(Spring,Spring进阶之路,spring,注解,注解方式实现Bean的注入)