一、通过注解(annotation)装配Bean
通过之前的学习,我们已经知道如何使用XML装配Bean,但是更多的时候已经不再推荐使用XML的方式去装配Bean,更多的时候会考虑注解(annotation)的方式去装配Bean。
使用注解的方式可以减少XML的配置,注解功能更为强大,它既能实现XML的功能,也能提供自动装配的功能,采用了自动装配后,程序员所需要做的决断就减少了,更加有利于对程序的开发,
这就是"约定优于配置"的开发原则。
在Spring中,它提供了两种方式来让Spring IoC容器发现Bean。
1.组件扫描:通过定义资源的方式,让Spring IoC容器扫描对应的包,从而把Bean装配进来。
2.自动装配:通过注解定义,使得一些依赖关系可以通过注解来完成。
通过扫描和自动装配,大部分的工程师都可以使用Java配置完成,而不是XML,这样可以有效地减少配置和引入大量ML,它解决了在Spring3之前的版本需要大量的XML的配置的问题,
这些问题曾被许多开发者诟病。由于目前注解已经成为Spring开发的主流,同时也必须了解不使用XML同样会存在一些弊端,比如系统存在多个公共配置文件(比如多个properties和xml文件),
如果写在注解里,那么这些公共配置文件就会比较分散,这样 不利于统一的管理,又或者一些来至第三方的类,而不是我们系统开发的配置文件,这时利用xml配置就会比较容易管理。
目前企业所流行的方式是,注解为主,xml为辅。

1、使用@Component装配Bean
@Component:代表Spring IoC容器会把这个类扫描生成Bean实例,其中value属性表示这个Bean的id,语法格式:@Component("beanId")或者@Component(value="beanId")
@Value:代表值的注入,注入的时候Spring IoC会自动转型。
@ComponentScan:代表进行扫描,默认是扫描当前把的路径,POJO的包名和它必须保持一致才能扫描,否则是不会自动装配Bean的。这里需要特别说明一下:

@ComponentScan存在2个配置项:第一个是basePackages,它是由base和package两个单词组成的,而package还使用了复数,意味着它可以配置一个Java包的数组,Spring会根据他的配置
扫描对应的包和子包,将配置好的Bean装配进来;第二个是basePackageClasses,他是由base,package,class三个单词组成,采用复数,意味着可以配置多个类,Spring可以根据配置的类所在的包
进行扫描装配对应配置的Bean。

贴出测试代码:

---------------------->以下着重测试注解:@Component、@Value()<-----------------------------

创建一个:UserBean.java

 package com.xfwl.spring.annotation;

 import org.springframework.beans.factory.annotation.Value;
import org.springframework.context.annotation.ComponentScan;
import org.springframework.stereotype.Component; /**
* 测试注解:@Component装配Bean
* @author Jason
*
*/
@ComponentScan //启动扫描当前所在包的Bean,注入Spring IoC容器
@Component("user") //注入user //@Component("user")或者@Component(value="user")
public class UserBean {
@Value("xfww")
private String uname;
@Value("123456")
private String upwd;
public UserBean(){}
public UserBean(String uname,String upwd){
this.uname=uname;
this.upwd=upwd;
}
public String getUname() {
return uname;
}
public void setUname(String uname) {
this.uname = uname;
}
public String getUpwd() {
return upwd;
}
public void setUpwd(String upwd) {
this.upwd = upwd;
}
@Override
public String toString() {
return "UserBean [uname=" + uname + ", upwd=" + upwd + "]";
}
}

创建一个:Manager.java

 package com.xfwl.spring.annotation;

 import java.util.List;
import java.util.Map;
import java.util.Properties;
import java.util.Set; import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Component;
/**
* 注解测试:@Autoired 自动装配
* @function
* @author 小风微凉
* @time 2018-7-10 上午11:32:01
*/
@Component("manager")
public class Manager{
@Autowired
private long id;
@Autowired
private String mname;
@Autowired
private int mage;
/******getter和setter***********/
public long getId() {
return id;
}
public void setId(long id) {
this.id = id;
}
public String getMname() {
return mname;
}
public void setMname(String mname) {
this.mname = mname;
}
public int getMage() {
return mage;
}
public void setMage(int mage) {
this.mage = mage;
}
}

创建一个测试类:TestAnnotation.java

package com.xfwl.spring.annotation;
import org.springframework.context.ApplicationContext;
import org.springframework.context.annotation.AnnotationConfigApplicationContext; /**
* Spring Ioc测试
* @function
* @author 小风微凉
* @time 2018-7-10 上午9:55:15
*/
public class TestAnnotation {
//项目相对路径
private static final String xmlRelPath="com/xfwl/spring/assem/applicationContext.xml";
public static void main(String[] args) {
//通过注解拿到Spring IoC容器对象
ApplicationContext ctx=new AnnotationConfigApplicationContext(UserBean.class);
//获取Bean对象
UserBean user=(UserBean) ctx.getBean("user");
System.out.println(user.toString());
}
}

测试结果:(上面注解正常运行

 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.
UserBean [uname=xfww, upwd=123456]

---------------------->以下着重测试注解:@ComponentScan<-----------------------------

创建几个测试类如下:

ComponScan_1.java

 package com.xfwl.spring.annotation.qualifier;

 import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.context.annotation.ComponentScan;
import org.springframework.context.annotation.Primary;
import org.springframework.stereotype.Component; /**
* 测试注解@Qualifier
* @function
* @author 小风微凉
* @time 2018-7-12 上午11:55:26
*/
@Component("serviceImp")
//@Primary
public class ServiceImpl implements IServices {
@Autowired(required=true)
private UserBean user;
@Override
public void show() {
System.out.println(this.user.toString());
}
/**********getter和setter*******************/
public UserBean getUser() {
return user;
}
public void setUser(UserBean user) {
this.user = user;
}
}

ComponScan_2.java

 package com.xfwl.spring.annotation.scans;

 import org.springframework.beans.factory.annotation.Value;
import org.springframework.stereotype.Component; /**
* 测试:
* [1].扫描注解@ComponnetScan的属性basePackages和basePackageClasses配置项的使用
* @function
* @author 小风微凉
* @time 2018-7-12 上午9:16:15
*/
@Component("scan_2")
public class ComponScan_2 {
@Value("scan_2_id")
private String id;
@Value("scan_2_info")
private String info;
/*******getter和setter************/
public String getId() {
return id;
}
public void setId(String id) {
this.id = id;
}
public String getInfo() {
return info;
}
public void setInfo(String info) {
this.info = info;
}
/*******重写toString方法******************/
@Override
public String toString() {
return "ComponScan_2 [id=" + id + ", info=" + info + "]";
}
}

一个管理类:ScanManage.java,且这个类中,使用扫面注解:@ComponentScan(basePackageClasses={ComponScan_1.class,ComponScan_2.class,ScanManage.class})

 package com.xfwl.spring.annotation.scans;

 import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.context.annotation.ComponentScan;
import org.springframework.stereotype.Component; /**
* 测试:
* [1].扫描注解@ComponnetScan的属性basePackages和basePackageClasses配置项的使用。
* [2].自动装配注解@Autowired,配置在属性字段或者属性字段对应的setter方法上。
* @function
* @author 小风微凉
* @time 2018-7-12 上午10:06:55
*/
//配置注解
@Component("scanManage")
//第二种方式:配置指定的类,通过反射注入IoC
@ComponentScan(basePackageClasses={ComponScan_1.class,ComponScan_2.class,ScanManage.class})
public class ScanManage {
@Autowired(required=true)
private ComponScan_1 scan_1;
private ComponScan_2 scan_2;
/*******getter和setter************/
public ComponScan_1 getScan_1() {
return scan_1;
}
public void setScan_1(ComponScan_1 scan_1) {
this.scan_1 = scan_1;
}
public ComponScan_2 getScan_2() {
return scan_2;
}
@Autowired(required=true)
public void setScan_2(ComponScan_2 scan_2) {
this.scan_2 = scan_2;
}
/*******重写toString方法******************/
@Override
public String toString() {
return "ScanManage [scan_1=" + scan_1.getId() + ", scan_2=" + scan_2.getId() + "]";
}
}

一个测试类:TestScan.java

 package com.xfwl.spring.annotation;

 import org.springframework.context.ApplicationContext;
import org.springframework.context.annotation.AnnotationConfigApplicationContext; import com.xfwl.spring.annotation.scans.ComponScan_1;
import com.xfwl.spring.annotation.scans.ComponScan_2;
import com.xfwl.spring.annotation.scans.ScanManage;
import com.xfwl.spring.annotation.scans2.ScanManage2; public class TestScan {
//项目相对路径
private static final String xmlRelPath="com/xfwl/spring/assem/applicationContext.xml";
public static void main(String[] args) {
//通过注解拿到Spring IoC容器对象
/**
* ScanManage:使用了@ComponnetScan的basePackageClasses的配置项
* ScanManage2:使用了@ComponnetScan的basePackages的配置项
*/
20 //ApplicationContext ctx=new AnnotationConfigApplicationContext(ScanManage.class);//不可以把@ComponentScan注解在接口中,会报错
21 ApplicationContext ctx=new AnnotationConfigApplicationContext(ScanManage2.class);
//获取Bean对象
ComponScan_1 scan1_1=(ComponScan_1) ctx.getBean("scan_1");
System.out.println(scan1_1.toString());
ComponScan_2 scan1_2=(ComponScan_2) ctx.getBean("scan_2");
System.out.println(scan1_2.toString());
ScanManage scan1Manage1=(ScanManage) ctx.getBean("scanManage");
System.out.println(scan1Manage1.toString());
}
}

测试结果:以上加粗,红色的代码,均可以正常运行,说明注解正常在跑。

总结一下:  

不可以把@ComponentScan注解在接口中,会报错

2、获取Spring IoC容器对象的2中形式:

第一种:获取xml配置文件,产生Spring IoC容器对象,有如下几种形式。
FileSystemXmlApplicationContext ctx = new FileSystemXmlApplicationContext(xmlAbsPath);
ApplicationContext ctx=new ClassPathXmlApplicationContext(xmlRelPath);
ClassPathXmlApplicationContext ctx=new ClassPathXmlApplicationContext(xmlRelPath);
第二种:通过注解获取Spring IoC容器对象
ApplicationContext ctx=new AnnotationConfigApplicationContext(UserBean.class);
特别说明:UserBean类中必须使用注解:@ComponentScan才可以扫描包下面的POJO装配Bean注入到Spring Ioc容器中。

3、自动装配-@Autowired

上面的注解都没有给Bean对象的属性注入对象,关于这个问题,在注解中略微有点复杂,在大部分情况下建议使用自动装配,因为这样可以减少配置的复杂度,
所以这里先介绍自动装配。
通过学习Spring IoC容器,我们知道Spring是先完成Bean的定义和生成,然后寻找需要注入的资源。也就是当Spring生成所有的Bean后,然后发现这个注解,
它就会在Bean中查找,然后找到对应的类型,将其注入进来,这样就完成了依赖注入了。所谓自动装配技术是一种由Spring自己发现对应的Bean,自动完成装配工作的方式,
它会应用到一个十分常用的注解@Autowrired,这个时候Spring IoC容器会自动根据类型去寻找定义的Bean然后将其注入。
需要注意的是,一旦配置了@Autowrired,在Spring IoC容器中就必须存在对应bean对象,否则就会Bean查找失败,在默认的情况下寻找失败它就会抛出异常,也就是说默认
情况下,Spring IoC容器会认为一定要找到对应的Bean来注入这个属性字段,有时候这并不是一个真实的需要,比如日志,有时候我们会觉得这个字段可有可无,这个时候可以通过
@Autowired的配置项required来改变它,比如@Autowired(required=false)。

以下贴出测试代码:

@Autowired 注解普通属性字段:

 package com.xfwl.spring.annotation;

 import java.util.List;
import java.util.Map;
import java.util.Properties;
import java.util.Set; import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Component;
/**
* 注解测试:@Autoired 自动装配
* @function
* @author 小风微凉
* @time 2018-7-10 上午11:32:01
*/
@Component("manager")
public class Manager{
@Autowired
private long id;
@Autowired
private String mname;
@Autowired
private int mage;
/******getter和setter***********/
public long getId() {
return id;
}
public void setId(long id) {
this.id = id;
}
public String getMname() {
return mname;
}
public void setMname(String mname) {
this.mname = mname;
}
public int getMage() {
return mage;
}
public void setMage(int mage) {
this.mage = mage;
}
}

@Autowired 注解引用类型字段:

 package com.xfwl.spring.annotation.qualifier;

 import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.context.annotation.ComponentScan;
import org.springframework.context.annotation.Primary;
import org.springframework.stereotype.Component; /**
* 测试注解@Qualifier
* @function
* @author 小风微凉
* @time 2018-7-12 上午11:55:26
*/
@Component("serviceImp")
//@Primary
public class ServiceImpl implements IServices {
@Autowired(required=true)
private UserBean user;
@Override
public void show() {
System.out.println(this.user.toString());
}
/**********getter和setter*******************/
public UserBean getUser() {
return user;
}
public void setUser(UserBean user) {
this.user = user;
}
}

正如之前所谈到的在默认情况下是必须注入成功的,所以这里的required的默认值为true。当把配置修改为false时,就告诉Spring IoC容器,假如在已经定义好的Bean中查找
不到的对应的类型,允许不注入,这样也就没有异常抛出,只是这个字段可能为空,开发者自行校验,以免发生空指针异常。在大部分情况下,都不需要这样修改。
@Autowired除可以配置在属性字段上外,还可以配置在方法上,常见的Bean的setter方法也可以使用它完成注入。

     private UserBean user;
/**********getter和setter*******************/
@Autowired(required=true)
public void setUser(UserBean user) {
this.user = user;
}

在大部分配置中,推荐使用@Autowired注解,这是Spring IoC容器自动装配完成的,使得配置大幅度减少,满足约定优于配置的原则,增强程序的健壮性。

4、自动装配的歧义性(@Primary和@Qualifier)
        上面谈到了@Autowired注解,它可以完成一些自动装配功能,并且使用方式十分简单,但是有时候这样的当时并不能使用。这一切的根源来至于按类型的方式,按照Spring的建议,
在大部分情况下会使用接口编程,但是定义一个接口,并不一定只有一个与之对应的实现类。换句话说,一个接口可以有多个实现类。
下面介绍2中消除歧义性的注解,其消除歧义性的理念也不同:
第一种注解@Primary:
注解@Primary代表首要的,当Spring IoC通过一个接口或者抽象类注入对象的时候,由于存在多个实现类或者具体类,就会犯糊涂,不知道采用哪个类为好。
注解@Primary则是告诉Spring IoC容器,请优先该类注入。也就是说,使用了@Primary注解的类将被Spring IoC容器作为优先选择被注入,这样可以消除歧义性。
同样的,或许你会想到将@Primary注解到同一个接口的多个实现类中,这样就会存在多个首选的接口了,但是在Spring IoC容器中这样的定义是允许的,只是在注入的时候将
会抛出异常。但是无论如何@Primary只能解决首要性的问题,而不能解决选择性的问题,简而言之,它不能选择使用接口具体的实现类去注入,仅仅提供一个首要性的选择倾向。

创建2个实现同一个接口的实现子类:

实体POJO类:UserBean.java

 package com.xfwl.spring.annotation.qualifier;

 import org.springframework.beans.factory.annotation.Value;
import org.springframework.context.annotation.ComponentScan;
import org.springframework.stereotype.Component; /**
* 测试注解:@Component装配Bean
* @author Jason
*
*/
@Component("user") //注入user //@Component("user")或者@Component(value="user")
public class UserBean {
@Value("xfww")
private String uname;
@Value("123456")
private String upwd;
public UserBean(){}
public UserBean(String uname,String upwd){
this.uname=uname;
this.upwd=upwd;
}
public String getUname() {
return uname;
}
public void setUname(String uname) {
this.uname = uname;
}
public String getUpwd() {
return upwd;
}
public void setUpwd(String upwd) {
this.upwd = upwd;
}
@Override
public String toString() {
return "UserBean [uname=" + uname + ", upwd=" + upwd + "]";
} }

接口:IServices.java

 package com.xfwl.spring.annotation.qualifier;

 import org.springframework.context.annotation.ComponentScan;
import org.springframework.stereotype.Component; /**
* 服务接口:测试注解@Qualifier
* @function
* @author 小风微凉
* @time 2018-7-12 上午11:52:29
*/
@Component(value="service")
public interface IServices {
public void show();
}

第一个实现子类:ServiceImpl.java

 package com.xfwl.spring.annotation.qualifier;

 import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.context.annotation.ComponentScan;
import org.springframework.context.annotation.Primary;
import org.springframework.stereotype.Component; /**
* 测试注解@Qualifier
* @function
* @author 小风微凉
* @time 2018-7-12 上午11:55:26
*/
@Component("serviceImp")
@Primary
public class ServiceImpl implements IServices {
@Autowired(required=true)
private UserBean user;
@Override
public void show() {
System.out.println(this.user.toString());
}
/**********getter和setter*******************/
public UserBean getUser() {
return user;
}
public void setUser(UserBean user) {
this.user = user;
}
}

第二个实现子类:ServiceImpl2.java(在此类中使用注解@Primary)

 package com.xfwl.spring.annotation.qualifier;

 import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.context.annotation.ComponentScan;
import org.springframework.context.annotation.Primary;
import org.springframework.stereotype.Component; /**
* 测试注解@Qualifier
* @function
* @author 小风微凉
* @time 2018-7-12 上午11:55:26
*/
@Component("serviceImp")
@Primary
public class ServiceImpl implements IServices {
@Autowired(required=true)
private UserBean user;
@Override
public void show() {
System.out.println(this.user.toString());
}
/**********getter和setter*******************/
public UserBean getUser() {
return user;
}
public void setUser(UserBean user) {
this.user = user;
}
}

在创建一个逻辑管理类:UserManage.java(在此类中添加注解扫描器)

 package com.xfwl.spring.annotation.qualifier;

 import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Qualifier;
import org.springframework.context.annotation.ComponentScan;
import org.springframework.stereotype.Component; /**
* 测试注解@Qualifier
* @function
* @author 小风微凉
* @time 2018-7-12 上午11:58:56
*/
@Component("manager")
@ComponentScan(basePackages={"com.xfwl.spring.annotation.qualifier"})//启动扫描当前所在包的Bean,注入Spring IoC容器
public class UserManage {
@Autowired(required=true)
//@Qualifier("serviceImp2")
private IServices service; public void show(){
this.service.show();
}
/**********getter和setter*******************/
public IServices getService() {
return service;
}
public void setService(IServices service) {
this.service = service;
}
}

再来一个测试类:TestScan.java

 package com.xfwl.spring.annotation.qualifier;

 import org.springframework.context.ApplicationContext;
import org.springframework.context.annotation.AnnotationConfigApplicationContext; import com.xfwl.spring.annotation.scans.ComponScan_1;
import com.xfwl.spring.annotation.scans.ComponScan_2;
import com.xfwl.spring.annotation.scans.ScanManage;
import com.xfwl.spring.annotation.scans2.ScanManage2; public class TestScan {
//项目相对路径
private static final String xmlRelPath="com/xfwl/spring/assem/applicationContext.xml";
public static void main(String[] args) {
ApplicationContext ctx=new AnnotationConfigApplicationContext(UserManage.class);
//获取Bean对象
UserManage manager=(UserManage) ctx.getBean("manager");
manager.show();
}
}

测试结果:注解正常运行

第二种注解@Qualifier:
正如上面谈及到的歧义性,一个重要的原因是Spring在寻找依赖注入的时候采用按类型注入引起的。处理按照类型查找Bean,Spring IoC容器最底层的接口BeanFactory,
也定义了按照名称查找的方法,如果采用名称查找的方法,而不是采用类型查找,那么不就可以消除歧义性了吗?答案是肯定的!而注解@Qualifier就是这样一个注解。

测试代码如下:(由于注解@Primary和注解@Qualifier的测试代码及其相似,所以以下会修改上面的代码来完成测试)

修改ServiceImpl.java,修改部分如下:

 package com.xfwl.spring.annotation.qualifier;

 import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.context.annotation.ComponentScan;
import org.springframework.context.annotation.Primary;
import org.springframework.stereotype.Component; /**
* 测试注解@Qualifier
* @function
* @author 小风微凉
* @time 2018-7-12 上午11:55:26
*/
@Component("serviceImp")
//@Primary
public class ServiceImpl implements IServices {
@Autowired(required=true)
private UserBean user;
@Override
public void show() {
System.out.println(this.user.toString());
}
/**********getter和setter*******************/
public UserBean getUser() {
return user;
}
public void setUser(UserBean user) {
this.user = user;
}
}

在UserManage.java中指定:@Qualifier("serviceImp2")

 package com.xfwl.spring.annotation.qualifier;

 import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Qualifier;
import org.springframework.context.annotation.ComponentScan;
import org.springframework.stereotype.Component; /**
* 测试注解@Qualifier
* @function
* @author 小风微凉
* @time 2018-7-12 上午11:58:56
*/
@Component("manager")
@ComponentScan(basePackages={"com.xfwl.spring.annotation.qualifier"})//启动扫描当前所在包的Bean,注入Spring IoC容器
public class UserManage {
@Autowired(required=true)
@Qualifier("serviceImp2")
private IServices service; public void show(){
this.service.show();
}
/**********getter和setter*******************/
public IServices getService() {
return service;
}
public void setService(IServices service) {
this.service = service;
}
}

测试结果:注解正常运行

5、装载带有参数的构造方法类:

贴出测试代码:

 package com.xfwl.spring.annotation.qualifier;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Component;
@Component("serviceImp")
public class ServiceImpl implements IServices {
private UserBean user;
public ServiceImpl(@Autowired UserBean user){//测试通过
this.user=user;
}
@Override
public void show() {
System.out.println(this.user.toString());
}
}

或者

 package com.xfwl.spring.annotation.qualifier;
import org.springframework.beans.factory.annotation.Qualifier;
import org.springframework.stereotype.Component;
@Component("serviceImp3")
public class ServiceImpl3 implements IServices {
private UserBean user;
public ServiceImpl3(@Qualifier UserBean user){//测试不通过,不支持注解@Qualifier注入构造器的参数
this.user=user;
}
@Override
public void show() {
System.out.println(this.user.toString());
}
}

从上面的代码,可以看出:这种注解并没有放在属性字段或者属性的setter方法上,而是直接放在构造器上的。

6、使用@Bean装配Bean

以上描述的用法都是通过@Componnet注解装配Bean,但是@Componnet只能注解在类上,不能注解在方法上。对于Java而言,大部分的开发都需要引入第三方的包(Jar文件),而且往往
并没有这些包的源码,这时候无法为这些包的类加入@Componnet注解,让他们变为开发环境的Bean.你可以使用新类扩展(extends)其包内的类,然后在新类上使用@Componnet,但是这样又显得
不伦不类。
     这个时候Spring给与一个注解@Bean,它可以注解到方法上,并且讲方法返回的对象作为Spring的Bean存放在IoC容器中。比如我们需要用到的DBCP数据源。

现在来测试一下:

 package com.xfwl.spring.annotation.bean;

 import java.util.Properties;

 import javax.sql.DataSource;

 import org.apache.commons.dbcp2.BasicDataSourceFactory;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.ComponentScan; @ComponentScan(basePackages={"com.xfwl.spring.annotation.bean"})
public class ManagerScan {
@Bean(name="ds")
public DataSource getDataSource(){
Properties props=new Properties();
props.setProperty("driverClassName", "oracle.jdbc.driver.OracleDriver");
props.setProperty("url", "jdbc:oracle:thin:@***.**.17.33:1521:**");
props.setProperty("username", "***");
props.setProperty("password", "***");
DataSource dataSource=null;
try {
dataSource=BasicDataSourceFactory.createDataSource(props);
} catch (Exception e) {
e.printStackTrace();
}
return dataSource;
}
}

以及

 package com.xfwl.spring.annotation.bean;
import java.util.Properties; import javax.sql.DataSource;
import org.apache.commons.dbcp2.BasicDataSourceFactory;
import org.springframework.context.ApplicationContext;
import org.springframework.context.annotation.AnnotationConfigApplicationContext;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.ComponentScan;
import org.springframework.stereotype.Component;
@Component("test")
public class TestBean {
public static void main(String[] args) {
//通过注解获取IoC容器对象
ApplicationContext ctx=new AnnotationConfigApplicationContext(ManagerScan.class);
System.out.println(ctx.getBean("ds").toString());
}
}

测试结果显示:可以从Spring IoC容器中拿到ds这个Bean对象。

7、注解自定义Bean的初始化和销毁方法:

  注解@Bean不能使用在类的标注上,它主要使用在方法上,@Bean的配置项包含4个配置项:

  • name:是一个字符串数组,允许配置多个BeanName。
  • autowire:标志是否是一个引用的Bean对象,默认值是AutoWire.No。
  • initKMethod:自定义初始化方法。
  • destoryMethod:自定义销毁方法。

基于上面的描述,自定义初始化的方法是initMethod,销毁的方法则是destoryMethod。

贴出测试代码:

创建一个基本POJO类:UserBean.java (内置自定义的初始化和销毁方法

 package com.xfwl.spring.annotation.bean;

 import org.springframework.beans.factory.annotation.Value;
import org.springframework.context.annotation.ComponentScan;
import org.springframework.stereotype.Component; /**
* 测试注解:@Component装配Bean
* @author Jason
*
*/
@Component("user") //注入user //@Component("user")或者@Component(value="user")
public class UserBean {
@Value("xfww")
private String uname;
@Value("123456")
private String upwd;
public UserBean(){}
public UserBean(String uname,String upwd){
this.uname=uname;
this.upwd=upwd;
}
public String getUname() {
return uname;
}
public void setUname(String uname) {
this.uname = uname;
}
public String getUpwd() {
return upwd;
}
public void setUpwd(String upwd) {
this.upwd = upwd;
}
@Override
public String toString() {
return "UserBean [uname=" + uname + ", upwd=" + upwd + "]";
}
/**Bean生命周期测试**/
public void init(){
System.out.println("【"+this.getClass().getSimpleName()+"】执行自定义初始化方法!");
}
public void mydestory(){
System.out.println("【"+this.getClass().getSimpleName()+"】执行自定义销毁法!");
}
}

创建一个测试@Bean的类:(特别说明一下:注解@Configuration表示是告诉spring这个类是一个配置类,相当于我们的xml配置文件

 package com.xfwl.spring.annotation.bean;

 import org.springframework.beans.factory.BeanNameAware;
import org.springframework.beans.factory.DisposableBean;
import org.springframework.beans.factory.InitializingBean;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.ComponentScan;
import org.springframework.context.annotation.Configuration;
@Configuration
@ComponentScan(basePackages={"com.xfwl.spring.annotation.bean"})
public class ManagerScan{
@Bean(name={"tom","jack"},initMethod="init",destroyMethod="mydestory")
public UserBean getUser(@Autowired UserBean user){
return user;
}
}

创建一个测试类:

 package com.xfwl.spring.annotation.bean;
import java.util.Properties; import javax.sql.DataSource; import org.apache.commons.dbcp2.BasicDataSourceFactory;
import org.springframework.context.ApplicationContext;
import org.springframework.context.annotation.AnnotationConfigApplicationContext;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.ComponentScan;
import org.springframework.stereotype.Component;
@Component("test")
public class TestBean {
public static void main(String[] args) {
//通过注解获取IoC容器对象
AnnotationConfigApplicationContext ctx=new AnnotationConfigApplicationContext(ManagerScan.class);
UserBean user=(UserBean) ctx.getBean("tom");
System.out.println(user.toString());
ctx.close();
}
}

测试结果:

 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.
【UserBean】执行自定义初始化方法!
UserBean [uname=xfww, upwd=123456]
【UserBean】执行自定义销毁法!

JavaEE互联网轻量级框架整合开发(书籍)阅读笔记(10):通过注解(annotation)装配Bean之(@Configguration、@Component、@Value、@ComponentScan、@Autowired、@Primary、@Qualifier、@Bean)的更多相关文章

  1. JavaEE互联网轻量级框架整合开发(书籍)阅读笔记(12):XML配置自动扫描包,自动加载*.properties文件

    一.XML和注解组合使用 前几篇的测试案例都是在Java类中配置,现在换一种使用方式,在XML中配置,使Spring IoC容器在启动之后自动去扫描配置的包路径,扫描加载指定路径下的propertie ...

  2. JavaEE互联网轻量级框架整合开发(书籍)阅读笔记(6):Spring IOC容器学习(概念、作用、Bean生命周期)

    一.IOC控制反转概念 控制反转(IOC)是一种通过描述(在Java中可以是XML或者是注解)并通过第三方去生产或获取特定对象的方式. 主动创建模式,责任在于开发者,而在被动模式下,责任归于Ioc容器 ...

  3. JavaEE互联网轻量级框架整合开发(书籍)阅读笔记(2):SSM+Redis概念理解

    一.SSM+Redis的结构图 在Java互联网中,以Spring+SpringMVC+MyBatis(SSM)作为主流框架,SSM+Redis的结构图如下: 二.下面介绍它们各自承担的功能: 1.S ...

  4. JavaEE互联网轻量级框架整合开发(书籍)阅读笔记(1):Mybatis和Hibernate概念理解

    一.关键字说明: oop:面向对象 aop:面向切面 ioc:控制反转 orm:对象关系映射 pojo:数据库表映射的java实体类 二.常识说明:1.hibernate和mybatis都属于持久层. ...

  5. JavaEE互联网轻量级框架整合开发(书籍)阅读笔记(8):装配SpringBean概述(如何合理使用装配级别)

    一. 装配Bean概述  关于如何将自己开发的Bean配置到Spring IoC容器中,大部分场景下,我们都会使用ApplicationContext的具体实现类,因为对应的Spring IoC容器功 ...

  6. JavaEE互联网轻量级框架整合开发(书籍)阅读笔记(7):装配SpringBean·依赖注入装配

    一.依赖注入的三种方式      在实际环境中实现IoC容器的方式主要分为两大类,一类是依赖查找,依赖查找是通过资源定位,把对应的资源查找回来.另一类则是依赖注入.一般而言,依赖注入可分为3中方式: ...

  7. JavaEE互联网轻量级框架整合开发(书籍)阅读笔记(11):XML和Annotation装配Bean的混合使用(@ImportResource)

    一.XML和Annotation装配Bean如何合理使用 引入第三方资源包中类的时候,建议使用XML配置,而使用自己编写的Java类的时候,推荐使用Annotation注解配置Bean. 二.关于注解 ...

  8. JavaEE互联网轻量级框架整合开发(书籍)阅读笔记(9):通过XML装配Bean

    一.通过XML装配Bean 装配简易值 装配集合 命名空间装配(暂不测试) 二.测试例子 创建一个用户类:UserBean.java package com.xfwl.spring.assem; /* ...

  9. JavaEE互联网轻量级框架整合开发(书籍)阅读笔记(5):责任链模式、观察者模式

    一.责任链模式.观察者模式 1.责任链模式:当一个对象在一条链上被多个拦截器处理(烂机器也可以选择不拦截处理它)时,我们把这样的设计模式称为责任链模式,它用于一个对象在多个角色中传递的场景.   2. ...

随机推荐

  1. 【BZOJ】1012: [JSOI2008]最大数maxnumber /【洛谷】1198(线段树)

    Description 现在请求你维护一个数列,要求提供以下两种操作:1. 查询操作.语法:Q L 功能:查询当前数列中末尾L个数中的最大的数,并输出这个数的值.限制:L不超过当前数列的长度.2. 插 ...

  2. CentOS 7 安装Httpd(转)

    实验环境:CentOS7 实验步骤: 安装httpd服务:yum -y install httpd 关闭SELinux:setenforce 0 禁用防火墙策略:iptables -F 启动httpd ...

  3. 2_python之路之多级菜单

    python之路之多级菜单 1.使用知识点 (1)列表,字典的使用 (2)if条件判断语句 (3)for/while循环的使用 2.代码详细 #!/usr/bin/env python # _*_ c ...

  4. Cisco交换机配置VLAN与TRUNK

    0x00前言: 今日在学校里学习了如何搭建vlan和配置等等还有trunk. 由于快下课了.尽快写. 0x01准备: Cisco模拟器 0x02正文: 要求: VLAN 10 左边的IP:192.16 ...

  5. Spring高级话题

    Spring Aware 在实际项目中,你不可避免的要用到spring容器本身的功能资源,这时你的bean要意识到spring容器的存在,才能调用spring提供的资源.spring aware本来就 ...

  6. Spring实战之环境与profile

    1.配置profile bean Spring为环境相关的bean所提供的解决方案其实与构建时的方案没有太大的差别.当然,在这个过程中需要根据环境决定该创建哪个bean和不创建哪个bean.不过Spr ...

  7. winform中读取App.config中数据连接字符串

    1.首先要在工程引用中导入System.Configuration.dll文件的引用. 2.通过System.Configuration.ConfigurationManager.Connection ...

  8. Spring+Logback的集成总结

    现在好像用logback替换了log4j,具体看了一下介绍,感觉比log4j好很多. logback与log4j的区别如下 http://logback.qos.ch/reasonsToSwitch. ...

  9. 黑暗之光 Day3

    1. 滚动窗口 Scroll View. GameObject itemGo = NGUITools.AddChild(grid.gameObject, skillItemPrefab); grid. ...

  10. 后端生成二维码 - C#生成二维码(QR)

    最近在github上找到一个相对比较好的C#二维码生成类库.在这里和大家分享一下. github地址:https://github.com/codebude/QRCoder 把解决方案下载下来,编译生 ...