文章目录
前言
spring作为企业级web应用的常青树,已经陪伴我们技术人很多年的春秋,给我们企业带来了效率的提升,给我们的工作带来了更多的方便,作为我们技术人也是应该多了解她,就像对待老婆,女朋友,男朋友一样,多了解她才能少吵架,多一些幸福,那么今天我们就来看一下Spring、Bean的初始化。
一、引入spring-context依赖
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-context</artifactId>
<version>4.3.2.RELEASE</version>
</dependency>
二、编写配置类Config和测试类
1、定义配置类Config
/**
* @ClassName Config
* @Description TODO
* @Author 行则将至
* @Date 2021/11/13 23:28
* @Version 1.0
**/
@Configuration
public class Config {
@Bean(name = "mybean")
@Scope("prototype")
public MyBean createBean(){
return new MyBean();
}
@Bean(name = "factoryBean")
public MyBeanFactoryBean createMyBeanFactoryBean(){
return new MyBeanFactoryBean();
}
@Bean
public RoseFactory createRoseFactory(){
return new RoseFactory();
}
@Bean
public Rose createRose(RoseFactory roseFactory){
return roseFactory.createRose();
}
@Bean
public Animal createAnimal(){
return new Animal();
}
}
2、定义测试类
/**
* @ClassName App
* @Description TODO
* @Author M行则将至
* @Date 2021/11/13 23:26
* @Version 1.0
**/
public class App {
public static void main(String[] args) throws Exception {
AnnotationConfigApplicationContext context = new AnnotationConfigApplicationContext(Config.class, People.class,
UserDao.class, UserService.class, UserController.class);
// 通过Bean来定义
// MyBean bean = context.getBean(MyBean.class);
// MyBean beanProtoType = context.getBean(MyBean.class);
// System.out.println(bean);
// System.out.println(beanProtoType);
//
// Object createBean = context.getBean("mybean");
// System.out.println("name:" + createBean);
// 通过工厂类型来获取Bean
// MyBeanFactoryBean bean1 = context.getBean(MyBeanFactoryBean.class);
// System.out.println(bean1);
// System.out.println(bean1.getObject());
// System.out.println(bean1.getObjectType());
//
// Object factoryBean = context.getBean("factoryBean");
// System.out.println(factoryBean);
//
// Object bean = context.getBean("&factoryBean");
// System.out.println(bean);
// 通过其他bean进行创建,被需要的bean会被spring容器自己创建
// Rose bean = context.getBean(Rose.class);
// System.out.println(bean);
// 通过Component注解进行创建
// People bean = context.getBean(People.class);
// System.out.println(bean);
// Object people = context.getBean("people");
// System.out.println(people);
// 通过Repository注解进行创建
// UserDao bean1 = context.getBean(UserDao.class);
// System.out.println(bean1);
// Object userDao = context.getBean("userDao");
// System.out.println(userDao);
// 通过Service注解实现
// UserService bean = context.getBean(UserService.class);
// System.out.println(bean);
// 通过Controller注解实现
// UserController bean = context.getBean(UserController.class);
// System.out.println(bean);
// 通过Resource注解实现
// UserService bean = context.getBean(UserService.class);
// System.out.println(bean);
// bean初始化后的前后动作,通过实现接口InitializingBean和DisposableBean实现
// People bean = context.getBean(People.class);
// System.out.println(bean);
// 通过注解实现
Animal bean = context.getBean(Animal.class);
System.out.println(bean);
context.close();
}
}
2.1 通过Bean来定义
1、定义一个简单Bean
/**
* @ClassName MyBean
* @Description TODO
* @Author 行则将至
* @Date 2021/11/13 23:32
* @Version 1.0
**/
public class MyBean {
}
2、在配置类config中配置MyBean,其实和在xml中配置是一样的,代码如下:
/**
* @ClassName Config
* @Description TODO
* @Author 行则将至
* @Date 2021/11/13 23:28
* @Version 1.0
**/
@Configuration
public class Config {
@Bean(name = "mybean")
@Scope("prototype")
public MyBean createBean(){
return new MyBean();
}
}
3、测试(测试类通过上文中的运行即可)运行结果如下:
com.xzjz.simple.MyBean@6385cb26
4、spring中的Bean默认是单例的,但是可以通过Scope(“prototype”),来设置为原型模型,这样每次就可以获取一个新的对象,运行结果如下所示:
com.xzjz.simple.MyBean@19dc67c2
com.xzjz.simple.MyBean@221af3c0
name:com.xzjz.simple.MyBean@62bd765
兄弟姐们可以通过注释Config类中的注解来测试不同的情况,其中Bean如果不定义别名的话,context.getBean(“方法名”)获取对象,在这里就是context.getBean(“createBean”)
2.2 通过工厂类型来获取Bean
1、定义我们自己的对象
/**
* @ClassName BeanFactory
* @Description TODO
* @Author 行则将至
* @Date 2021/11/14 12:09
* @Version 1.0
**/
public class BeanFactory {
}
2、定义MyBeanFactoryBean ,实现FactoryBean并实现其的方法,getObject返回对象,getObjectType返回对象的类型。
/**
* @ClassName MyBeanFactoryBean
* @Description TODO
* @Author 行则将至
* @Date 2021/11/14 12:05
* @Version 1.0
**/
public class MyBeanFactoryBean implements FactoryBean<BeanFactory> {
/**
* 获取对象
* @return
* @throws Exception
*/
@Override
public BeanFactory getObject() throws Exception {
return new BeanFactory();
}
/**
* 获取对象的类型
* @return
*/
@Override
public Class<?> getObjectType() {
return BeanFactory.class;
}
}
3、测试(测试类通过上文中的运行即可)运行结果如下,我们可以看到如果通过类型获取,那么得到的是MyBeanFactoryBean的类型,可以通过getObject和getObjectType获取对象及其类型,通过名字的话,获取到的是工厂对象生产出来的对象,我们一般在spring中是这种取法,但是我们还想获取其原型怎么办呢?即在名字前加&即可获得。
com.xzjz.factorybean.MyBeanFactoryBean@6b53e23f
com.xzjz.factorybean.BeanFactory@64d2d351
class com.xzjz.factorybean.BeanFactory
com.xzjz.factorybean.BeanFactory@1b68b9a4
com.xzjz.factorybean.MyBeanFactoryBean@6b53e23f
4、步骤4中的&符是怎么知道的呢?我们看源码BeanFactory,定义了一个工厂bean的前缀,就是从这里获取的,上边的注释也解释的非常清楚。
public interface BeanFactory {
/**
* Used to dereference a {@link FactoryBean} instance and distinguish it from
* beans <i>created</i> by the FactoryBean. For example, if the bean named
* {@code myJndiObject} is a FactoryBean, getting {@code &myJndiObject}
* will return the factory, not the instance returned by the factory.
*/
String FACTORY_BEAN_PREFIX = "&";
//后边的其他代码省略,有兴趣的可以自行查看
}
2.3 通过其他bean进行创建,被需要的bean会被spring容器自己创建
1、定义我们自己的对象rose
/**
* @ClassName Rose
* @Description TODO
* @Author 行则将至
* @Date 2021/11/14 12:31
* @Version 1.0
**/
public class Rose {
}
2、定义产生该对象的工厂类RoseFactory
/**
* @ClassName RoseFactory
* @Description TODO
* @Author 行则将至
* @Date 2021/11/14 12:32
* @Version 1.0
**/
public class RoseFactory {
public Rose createRose(){
return new Rose();
}
}
3、测试(测试类通过上文中的运行即可)运行结果如下,缺少的roseFactory对象,spring容器会自动寻找上下文中的对象进行注入,如果没有的话会报错could not autowire,No Beans of ‘RoseFactory’ type found
com.xzjz.yilai.Rose@6328d34a
2.4 通过Component注解进行声明
1、定义bean
/**
* @ClassName People
* @Description TODO
* @Author 行则将至
* @Date 2021/11/14 13:08
* @Version 1.0
**/
@Component("people")
public class People {
}
2、测试(查看上文中App的定义)运行结果如下:
com.xzjz.component.People@145eaa29
com.xzjz.component.People@145eaa29
2.5 通过Repository创建对象
1、定义UserDao对象
/**
* @ClassName UserDao
* @Description TODO
* @Author 行则将至
* @Date 2021/11/14 13:23
* @Version 1.0
**/
@Repository //该注解一般用在dao层上
public class UserDao {
}
2、测试结果如下所示
com.xzjz.repository.UserDao@41ee392b
com.xzjz.repository.UserDao@41ee392b
2.6 通过Service注解实现
1、创建UserService
/**
* @ClassName UserService
* @Description TODO
* @Author 行则将至
* @Date 2021/11/14 13:28
* @Version 1.0
**/
@Service //该注解一般用在业务层
public class UserService {
}
2、测试结果如下所示:
com.xzjz.service.UserService@157632c9
2.7 通过Controller注解实现
1、创建UserController
/**
* @ClassName UserController
* @Description TODO
* @Author 行则将至
* @Date 2021/11/14 13:32
* @Version 1.0
**/
@Controller //该注解一般在视图层
public class UserController {
}
2、测试如下所示:
com.xzjz.controller.UserController@275710fc
2.8 通过Resource初始化
1、定义Resource修饰的Bean
/**
* @ClassName UserService
* @Description TODO
* @Author 行则将至
* @Date 2021/11/14 13:28
* @Version 1.0
**/
@Service //该注解一般用在业务层
public class UserService {
@Resource
private People people;
@Override
public String toString() {
return "UserService{" +
"people=" + people +
'}';
}
}
2、测试运行如下,可以看到people已经被初始化
UserService{people=com.xzjz.component.People@568bf312}
3、其实还有一个JSR-330的注解Inject注解,需要导入javax.inject包,这个咱们自行研究
2.9 bean初始化后的前后动作,通过实现接口InitializingBean和DisposableBean实现
1、实现InitializingBean和DisposableBean
/**
* @ClassName People
* @Description TODO
* @Author 行则将至
* @Date 2021/11/14 13:08
* @Version 1.0
**/
@Component("people")
public class People implements InitializingBean, DisposableBean {
@Override
public void afterPropertiesSet() throws Exception {
System.out.println("=====afterPropertiesSet=======");
}
@Override
public void destroy() throws Exception {
System.out.println("========destroy===========");
}
}
2、测试结果如下:
=====afterPropertiesSet=======
com.xzjz.component.People@589b3632
========destroy===========
2.10 通过注解实现bean初始化时的动作
1、定义bean
/**
* @ClassName Animal
* @Description TODO
* @Author 行则将至
* @Date 2021/11/14 15:23
* @Version 1.0
**/
public class Animal {
@PostConstruct
public void before(){
System.out.println("======before======");
}
@PreDestroy
public void after(){
System.out.println("=======after======");
}
}
2、测试结果如下:
======before======
com.xzjz.afterbefore.Animal@2145433b
=======after======
三、结语
道阻且长,行则将至,行而不辍,未来可期,加油。
如果你热爱编码,欢迎微信搜索程序猿每日分享,和我们大家一起打怪升级。