7、SSM框架-Spring之IOC的注解注入(7)

用注解来向Spring容器注册Bean。需要在applicationContext.xml中注册<context:component-scan base-package=”pagkage1[,pagkage2,…,pagkageN]”/>。
如:在base-package指明一个包
 <context:component-scan base-package="cn.gacl.java"/>
表明cn.gacl.java包及其子包中,如果某个类的头上带有特定的注解【@Component/@Repository/@Service/@Controller】,就会将这个对象作为Bean注册进Spring容器。也可以在<context:component-scan base-package=” ”/>中指定多个包,如:
 <context:component-scan base-package="cn.gacl.dao.impl,cn.gacl.service.impl,cn.gacl.action"/>
多个包逗号隔开。

以下为常用的四个注解,关于其他的注解,我会在后面的时候进行总结和整理,此处对以下四个有个大体的了解即可

一、基于@Component注解的配置

spring 2.5 中除了提供 @Component 注释外,还定义了几个拥有特殊语义的注释,它们分别是:@Repository、@Service 和 @Controller。
在目前的 Spring 版本中,这 3 个注释和 @Component 是等效的,但是从注释类的命名上,很容易看出这 3 个注释分别和持久层、业务层和控制层(Web 层)相对应。
虽然目前这3 个注释和 @Component 相比没有什么新意,但 Spring 将在以后的版本中为它们添加特殊的功能。所以,如果 Web 应用程序采用了经典的三层分层结构的话,最好在持久层、业务层和控制层分别采用上述注解对分层中的类进行注释。

1、@controller 控制器(注入服务)

2、@service 服务(注入dao)

3、@repository dao(实现dao访问)

4、@component (把普通pojo实例化到spring容器中,相当于配置文件中的<bean id="" class=""/>)


@component用法如下:

  1. @Component("userDao")  
  2. public class UserDaoImp implements UserDao{  
  3.   
  4.     @Override  
  5.     public void add(User user) {  
  6.         System.out.println(user.getName());    
  7.         System.out.println(user.getSex());   
  8.         System.out.println(user.getAge());   
  9.     }  
  10.   
  11. }  
  1. @Component("userDao")  
  2. public class UserDaoImp implements UserDao{  
  3.   
  4.     @Override  
  5.     public void add(User user) {  
  6.         System.out.println(user.getName());    
  7.         System.out.println(user.getSex());   
  8.         System.out.println(user.getAge());   
  9.     }  
  10.   
  11. }  
@Component("userDao")
public class UserDaoImp implements UserDao{

	@Override
	public void add(User user) {
		System.out.println(user.getName());  
        System.out.println(user.getSex()); 
        System.out.println(user.getAge()); 
	}

}

  在类上使用@Component注解,表示该类定义为Spring管理Bean,使用默认value(可选)属性表示Bean标识符。

相当于:

  1. <bean id="userDao" class="com.mucfc.dao.UserDao"/>  
  1. <bean id="userDao" class="com.mucfc.dao.UserDao"/>  
         <bean id="userDao" class="com.mucfc.dao.UserDao"/>
@Component,@Service,@Controller,@Repository注解的类,并把这些类纳入进spring容器中管理。

下面写这个是引入component的扫描组件
  1. <!-- 配置的bean所在包的位置 -->    
  2. lt;context:component-scan base-package="com.mucfc" />  
  1. <!-- 配置的bean所在包的位置 -->    
  2. lt;context:component-scan base-package="com.mucfc" />  
	 <!-- 配置的bean所在包的位置 -->  
	<context:component-scan base-package="com.mucfc" />
其中base-package为需要扫描的包(含所有子包)

@Component泛指组件,当组件不好归类的时候,我们可以使用这个注解进行标注。

本文工程免费下载

二、使用实例

User.Java:用@Repository注解

  1. package com.mucfc.model;  
  2. import org.springframework.context.annotation.Scope;  
  3. import org.springframework.stereotype.Repository;  
  4.   
  5. @Repository("user")  
  6. @Scope("prototype")  
  7. //@Repository用于标注数据访问组件,即DAO组件  
  8. //@Scope("prototype")让其每次返回不同的实例,默认是单例  
  9. public class User {  
  10.     private String name;  
  11.     private String sex;  
  12.     public String getName() {  
  13.         return name;  
  14.     }  
  15.     public void setName(String name) {  
  16.         this.name = name;  
  17.     }  
  18.     public String getSex() {  
  19.         return sex;  
  20.     }  
  21.     public void setSex(String sex) {  
  22.         this.sex = sex;  
  23.     }  
  24.     public int getAge() {  
  25.         return age;  
  26.     }  
  27.     public void setAge(int age) {  
  28.         this.age = age;  
  29.     }  
  30.     private int age;  
  31.       
  32.   
  33. }  
  1. package com.mucfc.model;  
  2. import org.springframework.context.annotation.Scope;  
  3. import org.springframework.stereotype.Repository;  
  4.   
  5. @Repository("user")  
  6. @Scope("prototype")  
  7. //@Repository用于标注数据访问组件,即DAO组件  
  8. //@Scope("prototype")让其每次返回不同的实例,默认是单例  
  9. public class User {  
  10.     private String name;  
  11.     private String sex;  
  12.     public String getName() {  
  13.         return name;  
  14.     }  
  15.     public void setName(String name) {  
  16.         this.name = name;  
  17.     }  
  18.     public String getSex() {  
  19.         return sex;  
  20.     }  
  21.     public void setSex(String sex) {  
  22.         this.sex = sex;  
  23.     }  
  24.     public int getAge() {  
  25.         return age;  
  26.     }  
  27.     public void setAge(int age) {  
  28.         this.age = age;  
  29.     }  
  30.     private int age;  
  31.       
  32.   
  33. }  
package com.mucfc.model;
import org.springframework.context.annotation.Scope;
import org.springframework.stereotype.Repository;

@Repository("user")
@Scope("prototype")
//@Repository用于标注数据访问组件,即DAO组件
//@Scope("prototype")让其每次返回不同的实例,默认是单例
public class User {
	private String name;
	private String sex;
	public String getName() {
		return name;
	}
	public void setName(String name) {
		this.name = name;
	}
	public String getSex() {
		return sex;
	}
	public void setSex(String sex) {
		this.sex = sex;
	}
	public int getAge() {
		return age;
	}
	public void setAge(int age) {
		this.age = age;
	}
	private int age;
	

}
UserDao.java
  1. package com.mucfc.dao;  
  2.   
  3. import com.mucfc.model.User;  
  4.   
  5. public interface UserDao {  
  6.     public void add(User user);  
  7. }  
  1. package com.mucfc.dao;  
  2.   
  3. import com.mucfc.model.User;  
  4.   
  5. public interface UserDao {  
  6.     public void add(User user);  
  7. }  
package com.mucfc.dao;

import com.mucfc.model.User;

public interface UserDao {
	public void add(User user);
}
UserDaoImp.java:用@Controller注解
  1. package com.mucfc.daoimp;  
  2.   
  3. import org.springframework.stereotype.Controller;  
  4.   
  5. import com.mucfc.dao.UserDao;  
  6. import com.mucfc.model.User;  
  7.   
  8. @Controller("userDao")  
  9. //@Controller用于标注控制层组件  
  10. public class UserDaoImp implements UserDao{  
  11.   
  12.     @Override  
  13.     public void add(User user) {  
  14.         System.out.println(user.getName());    
  15.         System.out.println(user.getSex());   
  16.         System.out.println(user.getAge());   
  17.     }  
  18.   
  19. }  
  1. package com.mucfc.daoimp;  
  2.   
  3. import org.springframework.stereotype.Controller;  
  4.   
  5. import com.mucfc.dao.UserDao;  
  6. import com.mucfc.model.User;  
  7.   
  8. @Controller("userDao")  
  9. //@Controller用于标注控制层组件  
  10. public class UserDaoImp implements UserDao{  
  11.   
  12.     @Override  
  13.     public void add(User user) {  
  14.         System.out.println(user.getName());    
  15.         System.out.println(user.getSex());   
  16.         System.out.println(user.getAge());   
  17.     }  
  18.   
  19. }  
package com.mucfc.daoimp;

import org.springframework.stereotype.Controller;

import com.mucfc.dao.UserDao;
import com.mucfc.model.User;

@Controller("userDao")
//@Controller用于标注控制层组件
public class UserDaoImp implements UserDao{

	@Override
	public void add(User user) {
		System.out.println(user.getName());  
        System.out.println(user.getSex()); 
        System.out.println(user.getAge()); 
	}

}

@Controller对应表现层的Bean,也就是Action,例如:

1 @Controller
2 @Scope("prototype")
3 public class UserAction extends BaseAction<User>{
4 ……
5 }

使用@Controller注解标识UserAction之后,就表示要把UserAction交给Spring容器管理,在Spring容器中会存在一个名字为"userAction"的action,这个名字是根据UserAction类名来取的。注意:如果@Controller不指定其value【@Controller】,则默认的bean名字为这个类的类名首字母小写,如果指定value【@Controller(value="UserAction")】或者【@Controller("UserAction")】,则使用value作为bean的名字

这里的UserAction还使用了@Scope注解,@Scope("prototype")表示将Action的范围声明为原型,可以利用容器的scope="prototype"来保证每一个请求有一个单独的Action来处理,避免struts中Action的线程安全问题。spring 默认scope 是单例模式(scope="singleton"),这样只会创建一个Action对象,每次访问都是同一Action对象,数据不安全,struts2 是要求每次次访问都对应不同的Action,scope="prototype" 可以保证当有请求的时候都创建一个Action对象

UserService.java:用@Service注解
  1. package com.mucfc.service;  
  2. import javax.annotation.Resource;  
  3.   
  4. import org.springframework.stereotype.Service;  
  5.   
  6. import com.mucfc.dao.UserDao;  
  7. import com.mucfc.model.User;  
  8.   
  9. @Service("userService")  
  10. //@Service用于标注业务层组件  
  11. public class UserService {  
  12.      //setter注入接口、面向接口编程    
  13.     private UserDao userdao ;    
  14.     public void add(User user){    
  15.         userdao.add(user) ;    
  16.     }    
  17.     public UserDao getUserdao() {    
  18.         return userdao;    
  19.     }    
  20.     //注解    
  21.     @Resource(name="userDao")    
  22.     public void setUserdao(UserDao userdao) {    
  23.         this.userdao = userdao;    
  24.     }    
  25. }  
  1. package com.mucfc.service;  
  2. import javax.annotation.Resource;  
  3.   
  4. import org.springframework.stereotype.Service;  
  5.   
  6. import com.mucfc.dao.UserDao;  
  7. import com.mucfc.model.User;  
  8.   
  9. @Service("userService")  
  10. //@Service用于标注业务层组件  
  11. public class UserService {  
  12.      //setter注入接口、面向接口编程    
  13.     private UserDao userdao ;    
  14.     public void add(User user){    
  15.         userdao.add(user) ;    
  16.     }    
  17.     public UserDao getUserdao() {    
  18.         return userdao;    
  19.     }    
  20.     //注解    
  21.     @Resource(name="userDao")    
  22.     public void setUserdao(UserDao userdao) {    
  23.         this.userdao = userdao;    
  24.     }    
  25. }  
package com.mucfc.service;
import javax.annotation.Resource;

import org.springframework.stereotype.Service;

import com.mucfc.dao.UserDao;
import com.mucfc.model.User;

@Service("userService")
//@Service用于标注业务层组件
public class UserService {
	 //setter注入接口、面向接口编程  
    private UserDao userdao ;  
    public void add(User user){  
        userdao.add(user) ;  
    }  
    public UserDao getUserdao() {  
        return userdao;  
    }  
    //注解  
    @Resource(name="userDao")  
    public void setUserdao(UserDao userdao) {  
        this.userdao = userdao;  
    }  
}
注意:在Action声明的“userService”变量的类型必须是“UserServiceImpl”或者是其父类“UserService”,否则由于类型不一致而无法注入,由于Action中的声明的“userService”变量使用了@Resource注解去标注,并且指明了其name = "userService",这就等于告诉Spring,说我Action要实例化一个“userService”,你Spring快点帮我实例化好,然后给我,当Spring看到userService变量上的@Resource的注解时,根据其指明的name属性可以知道,Action中需要用到一个UserServiceImpl的实例,此时Spring就会把自己创建好的名字叫做"userService"的UserServiceImpl的实例注入给Action中的“userService”变量,帮助Action完成userService的实例化,这样在Action中就不用通过“UserService userService = new UserServiceImpl();”这种最原始的方式去实例化userService了。如果没有Spring,那么当Action需要使用UserServiceImpl时,必须通过“UserService userService = new UserServiceImpl();”主动去创建实例对象,但使用了Spring之后,Action要使用UserServiceImpl时,就不用主动去创建UserServiceImpl的实例了,创建UserServiceImpl实例已经交给Spring来做了,Spring把创建好的UserServiceImpl实例给Action,Action拿到就可以直接用了。Action由原来的主动创建UserServiceImpl实例后就可以马上使用,变成了被动等待由Spring创建好UserServiceImpl实例之后再注入给Action,Action才能够使用。这说明Action对“UserServiceImpl”类的“控制权”已经被“反转”了,原来主动权在自己手上,自己要使用“UserServiceImpl”类的实例,自己主动去new一个出来马上就可以使用了,但现在自己不能主动去new“UserServiceImpl”类的实例,new“UserServiceImpl”类的实例的权力已经被Spring拿走了,只有Spring才能够new“UserServiceImpl”类的实例,而Action只能等Spring创建好“UserServiceImpl”类的实例后,再“恳求”Spring把创建好的“UserServiceImpl”类的实例给他,这样他才能够使用“UserServiceImpl”,这就是Spring核心思想“控制反转”,也叫“依赖注入”,“依赖注入”也很好理解,Action需要使用UserServiceImpl干活,那么就是对UserServiceImpl产生了依赖,Spring把Acion需要依赖的UserServiceImpl注入(也就是“给”)给Action,这就是所谓的“依赖注入”。对Action而言,Action依赖什么东西,就请求Spring注入给他,对Spring而言,Action需要什么,Spring就主动注入给他。
beans.xml'

  1. <?xml version="1.0" encoding="UTF-8"?>  
  2. <beans xmlns="http://www.springframework.org/schema/beans"  
  3.     xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:p="http://www.springframework.org/schema/p"  
  4.     xmlns:context="http://www.springframework.org/schema/context"  
  5.     xsi:schemaLocation="http://www.springframework.org/schema/beans    
  6.                 http://www.springframework.org/schema/beans/spring-beans-3.0.xsd    
  7.         http://www.springframework.org/schema/context    
  8.         http://www.springframework.org/schema/context/spring-context-3.0.xsd">  
  9.      <!-- 配置的bean所在包的位置 -->    
  10.     <context:component-scan base-package="com.mucfc" />  
  11. </beans>  
测试下:
  1. package com.mucfc.anno;  
  2.   
  3. import org.springframework.context.ApplicationContext;  
  4. import org.springframework.context.support.ClassPathXmlApplicationContext;  
  5.   
  6. import com.mucfc.model.User;  
  7. import com.mucfc.service.UserService;  
  8.   
  9.   
  10. public class Test {  
  11.   
  12.     public static void main(String[] args) {  
  13.         ApplicationContext applicationContext = new ClassPathXmlApplicationContext("beans.xml");  
  14.         UserService service=(UserService)applicationContext.getBean("userService");  
  15.         User user1 = (User) applicationContext.getBean("user");   
  16.         User user2 = (User) applicationContext.getBean("user");  
  17.         user1.setName("小明");  
  18.         user1.setSex("男");  
  19.         user1.setAge(22);  
  20.           
  21.         user2.setName("小红");  
  22.         user2.setSex("女");  
  23.         user2.setAge(18);  
  24.           
  25.         service.add(user1);  
  26.         service.add(user2);  
  27.     }  
  28.   
  29. }  
  1. package com.mucfc.anno;  
  2.   
  3. import org.springframework.context.ApplicationContext;  
  4. import org.springframework.context.support.ClassPathXmlApplicationContext;  
  5.   
  6. import com.mucfc.model.User;  
  7. import com.mucfc.service.UserService;  
  8.   
  9.   
  10. public class Test {  
  11.   
  12.     public static void main(String[] args) {  
  13.         ApplicationContext applicationContext = new ClassPathXmlApplicationContext("beans.xml");  
  14.         UserService service=(UserService)applicationContext.getBean("userService");  
  15.         User user1 = (User) applicationContext.getBean("user");   
  16.         User user2 = (User) applicationContext.getBean("user");  
  17.         user1.setName("小明");  
  18.         user1.setSex("男");  
  19.         user1.setAge(22);  
  20.           
  21.         user2.setName("小红");  
  22.         user2.setSex("女");  
  23.         user2.setAge(18);  
  24.           
  25.         service.add(user1);  
  26.         service.add(user2);  
  27.     }  
  28.   
  29. }  
package com.mucfc.anno;

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

import com.mucfc.model.User;
import com.mucfc.service.UserService;


public class Test {

	public static void main(String[] args) {
		ApplicationContext applicationContext = new ClassPathXmlApplicationContext("beans.xml");
		UserService service=(UserService)applicationContext.getBean("userService");
		User user1 = (User) applicationContext.getBean("user"); 
		User user2 = (User) applicationContext.getBean("user");
		user1.setName("小明");
		user1.setSex("男");
		user1.setAge(22);
		
		user2.setName("小红");
		user2.setSex("女");
		user2.setAge(18);
		
		service.add(user1);
		service.add(user2);
	}

}
结果:



当在组件类中使用了特定的注解之后,还需要在Spring的配置文件中声明 <context:component-scan>:

  • base-package属性指定一个需要扫描的基类包,Spring容器将会扫描整个基类包里及其子包中的所有类
  • 当需要扫描多个包时,可以使用逗号分隔
  • 如果仅希望扫描特定的类而非基包下的所有类,可使用resource-pattern属性过滤特定的类,实例:  
  • <context:include-filter>子节点表示要包含的目标类
  • <context:exclude-filter>子节点表示要排除在外的目标类
  • <context:component-scan>下可以拥有若干个<context:include-filter>和<context:exclude-filter>子节点
  • <context:include-filter>和<context:exclude-filter>子节点支持多种类型的过滤表
展开阅读全文

没有更多推荐了,返回首页