springboot是零配置的,所以必须了解到spring4以后的注解注入bean的方式,才是学习springboot的前提。
现在先了解下,具体的几种注入bean到spring的方式。
也就是来玩一下这个
AnnotationConfigApplicationContext
这个类:
1.@Configurable
@Configurable
public class MyConfig {}
测试:
public static void main(String[] args) {
AnnotationConfigApplicationContext context = new AnnotationConfigApplicationContext(MyConfig.class);
System.out.println(context.getBean(MyConfig.class));
}
context.getBean有多种方式拿到bean,根据类class,类型等,
结果显示:容器拿到了这个bean:
2.@Bean
a.@bean注入
写个bean
public class MyBean {
}
在配置类中@Bean注入,scope配置指定单个或者多个实例方式注入
@Bean(name = "mybean")
@Scope("prototype")
public MyBean createMyBean(){
return new MyBean();
}
b.通过工厂方式注入
①官方提供,实现FactoryBean方式
public class RunableFactoryBean implements FactoryBean<Jeep> {
@Override
public Jeep getObject() throws Exception {
return new Jeep();
}
@Override
public Class<?> getObjectType() {
return Jeep.class;
}
@Override
public boolean isSingleton() {
return true;
}
}
@Configurable
public class MyConfig {
@Bean
public RunableFactoryBean createRunnableFactoryBean(){
return new RunableFactoryBean();
}
}
测试,测试1:拿到工厂(用&符号前缀),测试2:拿到工厂创建的bean
public class Test1 {
public static void main(String[] args) {
AnnotationConfigApplicationContext context = new AnnotationConfigApplicationContext(MyConfig.class);
System.out.println(context.getBean("&createRunnableFactoryBean"));
System.out.println(context.getBean(Jeep.class));
}
}
结果打印,都拿到了:
②自定义工厂方式
public class Car {
}
public class JeepFactory {
public Car create(){
return new Car();
}
}
先注入工厂,在通过工厂拿到bean
@Configurable
public class MyConfig {
@Bean
public JeepFactory creatJeepFactory(){
return new JeepFactory();
}
@Bean
public Car createJeep(JeepFactory factory){
return factory.create();
}
}
测试:略
3.初始化bean前后做一些事情:
在初始化后和销毁的时候调用一些方法:
1)方式1:实现InitializingBean(初始化后触发), DisposableBean(销毁的时候触发)
public class Cat implements InitializingBean, DisposableBean {
public Cat() {
System.out.println("=======init cat=========");
}
@Override
public void afterPropertiesSet() throws Exception {
System.out.println("=======afterPropertiesSet=========");
}
@Override
public void destroy() throws Exception {
System.out.println("=======destroy=========");
}
}
2)方式2:根据@Bean注解属性配置:
public class Dog {
public void init(){
System.out.println("init");
}
public void destory(){
System.out.println("destory");
}
}
@Bean(initMethod="init",destroyMethod="destory")
public Dog createDog(){
return new Dog();
}
3)方式3:@PostContruct
public class Animal {
@PostConstruct
public void inital(){
System.out.println("------initial--------");
}
@PreDestroy
public void close(){
System.out.println("------close--------");
}
}
4.组件注入方式
①普通组件@Component
@Component("myUser")
public class User {}
②Resposity ,常用于数据库处理bean
@Repository
public class UserDao {
}
③@Service,常用于业务处理类
@Service
public class UserService {
}
④@controller,常用于请求控制类
@Controller
public class UserController {
}
测试:
public class App {
public static void main(String[] args) {
AnnotationConfigApplicationContext context = new AnnotationConfigApplicationContext(MyConfig.class, User.class, UserDao.class,
UserService.class, UserController.class);
System.out.println(context.getBean(UserDao.class));
System.out.println(context.getBean(UserService.class));
System.out.println(context.getBean(UserController.class));
context.close();
}
}
运行结果:
5.依赖注入装配bean的方式
① @Autowire
如果多个bean,可以用@Quitifier(“XX”)具体指定,也可使用@Primary提高bean的优先级。
@Controller
public class UserController {
@Autowired
private UserDao userDao;
}
@Bean(name = "mybean")
@Primary
public MyBean createMyBean(){
return new MyBean();
}
②@Resource JSR 250的方式
@Controller
public class UserController {
@Autowired
private UserDao userDao;
@Resource
private UserService userService;
}
③@Inject JSR-330的方式
需要导包,因为spring项目默认不支持。
<dependency>
<groupId>javax.inject</groupId>
<artifactId>javax.inject</artifactId>
<version>1</version>
</dependency>
import org.springframework.stereotype.Component;
import javax.inject.Inject;
@Component("myUser")
public class User {
//JSR-330
@Inject
private Cat cat;
@Override
public String toString() {
return "User{" +
"cat=" + cat +
'}';
}
}
6.组件注入需要扫描包支持,如何扫描包?
方式1,在AnnotationConfigApplicationContext上直接写报名:
public class AnnocationClient {
public static void main(String[] args) {
AnnotationConfigApplicationContext context = new AnnotationConfigApplicationContext("com.springboot.demo1",
"com.springboot.demo2");
System.out.println(context.getBean(User.class));
System.out.println(context.getBean(UserDao.class));
System.out.println(context.getBean(UserController.class));
context.close();
}
}
方式2:扫描配置类::
可以写个扫描配置类:
@ComponentScan(basePackages = "com.springboot.demo1", excludeFilters= @Filter(type = FilterType.ASSIGNABLE_TYPE,classes={DogConfig.class}))
@Configurable
public class AnnocationScan {
}
注意,这里可以选择排除excludeFilters,后面说明咋排除。
public class AnnocationClient2 {
public static void main(String[] args) {
AnnotationConfigApplicationContext context = new AnnotationConfigApplicationContext(AnnocationScan.class);
// System.out.println(context.getBean(RunableFactoryBean.class));
System.out.println(context.getBean(User.class));
System.out.println(context.getBean(UserDao.class));
// System.out.println(context.getBean(Cat.class));
System.out.println(context.getBean(UserController.class));
}
}
配置排除的包:
点击排除的枚举类:
public enum FilterType {
ANNOTATION, //通过注解排除
ASSIGNABLE_TYPE, //通过指定的类排除
ASPECTJ, //通过aspectj表达式排除
REGEX, //通过正则表达式排除
CUSTOM; //自定义接口,实现org.springframework.core.type.filter.TypeFilter}排除
private FilterType() {
}
}
上面的截图是使用的ASSIGNABLE_TYPE自定类方式。
个人微信公号:
搜索: 怒放de每一天
不定时推送相关文章,期待和大家一起成长!!
完