package com.woniu.entity;
import lombok.AllArgsConstructor;
import lombok.Data;
import lombok.NoArgsConstructor;
import lombok.ToString;
@Data//生成get/set方法
@ToString//重写tostring
@AllArgsConstructor//生成全参构造
@NoArgsConstructor//生成无参构造
public class User {
private String name;
private Integer age;
private String sex;
}
package com.woniu;
import com.woniu.entity.User;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
/**
* 配置类
*/
@Configuration//配置类,相当于我们的配置文件
public class AppConfig {
@Bean//作用与applicationContext.xml中的<bean>作用相同,id为方法名,class为返回值类型
public User user(){
User user = new User();
user.setName("jack");
user.setAge(12);
user.setSex("male");
return user;
}
}
一.@Configuration和@Bean
@Configuration注解底层继承了@Component注解.项目启动后,AppConfig配置类也会交给ioc容器创建对象.再通过配置类内部每个方法上的@Bean,从而将这些方法返回的对象存到ioc容器中.
import org.springframework.context.annotation.AnnotationConfigApplicationContext;
public class AnnoTest {
@Test
public void before(){
ApplicationContext ac = new AnnotationConfigApplicationContext(AppConfig.class);
User user = ac.getBean("user", User.class);
System.out.println(user);
}
}
在使用applicationContext.xml文件时,需要通过new ClassPathXmlApplicationContext("applicationContext.xml")来获取容器对象.
但是使用配置类后,就要使用new AnnotationConfigApplicationContext(配置类类名.class)来获取容器对象.
配置类必须加注解@Configuration,来告诉spring,这是一个配置类.
可以使用ac.getBeanDefinitionNames();来获取容器内所有对象名
@Test
public void before(){
ApplicationContext ac = new AnnotationConfigApplicationContext(AppConfig.class);
User user = ac.getBean("user", User.class);
System.out.println(user);
String[] beanDefinitionNames = ac.getBeanDefinitionNames();
for (String beanDefinitionName : beanDefinitionNames) {
System.out.println(beanDefinitionName);
}
}
}
结果如下:可以看到配置类和自定义user类在容器内都创建了对象
org.springframework.context.annotation.internalConfigurationAnnotationProcessor
org.springframework.context.annotation.internalAutowiredAnnotationProcessor
org.springframework.context.annotation.internalCommonAnnotationProcessor
org.springframework.context.event.internalEventListenerProcessor
org.springframework.context.event.internalEventListenerFactory
appConfig
user
如果想配置扫描创建bean对象的注解(效果等同于spring配置文件中的
<context:component-scan base-package="com.company.service.impl"></context:component-scan>
二.@ComponentScan注解
可以在配置类AppConfig.java脑袋上加注解@ComponentScan(value="com.company.service.impl")
/**
* 配置类
*/
@Configuration//配置类,相当于我们的配置文件
@ComponentScan(value = "com.woniu")//等效于配置文件中的<context:component-scan base-package="xxx"/>
public class AppConfig {
@Bean//作用与applicationContext.xml中的<bean>作用相同,id为方法名,class为返回值类型
public User user(){
User user = new User();
user.setName("jack");
user.setAge(12);
user.setSex("male");
return user;
}
若想自定义bean对象的名字,不想要默认为方法名,只需要在@Bean后面加value,实例:
@Bean(value="myUser")
三.@Import注解
在配置类上加@Import({User.class,Student.class,Human.class....})
可以通过字节码文件实例化bean对象,并且存到ioc容器中.
四.使用ImportSelector接口.
让一个选择器类实现ImportSelector接口,重写selectImports方法.将想要放入容器的对象的类路径放入String数组,并作为该重写方法的返回值.
在@Imprt注解中加选择器类的字节码文件即可
public class MySelector implements ImportSelector {
@Override
public String[] selectImports(AnnotationMetadata importingClassMetadata) {
//将想要实例化的类的全限定名存到方法的返回数组中;
String[] arr = {"com.woniu.entity.Red","com.woniu.entity.White"};
return arr;
}
@Configuration//配置类,相当于我们的配置文件
@ComponentScan(value = "com.woniu")//等效于配置文件中的<context:component-scan base-package="xxx"/>
@Import({Blue.class, MySelector.class})
public class AppConfig {
@Bean(value = "myUser")//作用与applicationContext.xml中的<bean>作用相同,id为方法名,class为返回值类型
public User user(){
User user = new User();
user.setName("jack");
user.setAge(12);
user.setSex("male");
return user;
}
总结:
利用注解实例化对象的五种方式:
a.使用@Configuration实例化配置类
b.使用@Component,@Controller,@Service,@Repository(需要在配置类上加@ComponentScan)
c.在配置类的方法上使用@Bean.该方法必须要返回一个bean对象.
d.使用@Import
f.使用ImportSelector接口