002-Spring4 快速入门-项目搭建、基于注解的开发bean,Bean创建和装配、基于注解的开发bean,Bean初始化销毁、Bean装配,注解、Bean依赖注入
一、项目搭建
1、项目创建
eclipse→project explorer→new→Project→Maven Project
默认配置即可创建项目
2、spring配置
<dependency> <groupId>org.springframework</groupId> <artifactId>spring-context</artifactId> <version>4.3.13.RELEASE</version> </dependency>
3、配置项目编译目标版本
<properties> <project.build.sourceEncoding>UTF-8</project.build.sourceEncoding> <maven.compiler.source>1.8</maven.compiler.source> <maven.compiler.target>1.8</maven.compiler.target> </properties>
在项目上右键→maven→update project即可
二、基于注解的开发bean,Bean创建和装配
1、增加配置类,创建Bean
方法一、创建bean
增加注解@Configuration、@Bean、@Scope
@Configuration public class MyConfig { @Bean(name="myBean") @Scope("prototype") public MyBean createMyBean() { return new MyBean(); } }
方法二、使用FactoryBean创建,lambda方式
public class RunnableFactoryBean implements FactoryBean<Runnable>{ @Override public Runnable getObject() throws Exception { return ()->{}; } @Override public Class<?> getObjectType() { return Runnable.class; } @Override public boolean isSingleton() { return true; } }
如定义一个Jeep,讲工厂类改成
public class RunnableFactoryBean 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; } }
使用即可。
方法三、需要参数,默认会获取,自动注入
创建class Car
创建一个工厂
public class CarFactory { public Car create() { return new Car(); } }
在Config中添加
@Bean public CarFactory createCarFactory() { return new CarFactory(); } @Bean public Car createCar(CarFactory factory) { return factory.create(); }
使用即可:System.out.println(annotationConfigApplicationContext.getBean(Car.class));//名称获取
2、在方法入口增加配置
方法一、配置一个或多个指定的类型
AnnotationConfigApplicationContext annotationConfigApplicationContext = new AnnotationConfigApplicationContext(MyConfig.class);
方法二、配置指定扫描的包
AnnotationConfigApplicationContext context = new AnnotationConfigApplicationContext("com.lhx.spring.spring");
方法三、配置指定包,并且排除
@ComponentScan(basePackages="com.lhx.spring.spring",excludeFilters=@Filter(type=FilterType.ASSIGNABLE_TYPE))
FilterType有五种类型
ANNOTATION、ASSIGNABLE_TYPE、ASPECTJ、REGEX、CUSTOM
使用
建一个Dog类
public class Dog { public void init() { System.out.println("--------init------"); } public void destory() { System.out.println("--------destory------"); } }
增加一个DogConfig配置类
@Configuration public class DogConfig { @Bean(initMethod = "init", destroyMethod = "destory") public Dog createDog() { return new Dog(); } }
增加一个扫描配置类
@ComponentScan(basePackages="com.lhx.spring.spring",excludeFilters=@Filter(type=FilterType.ASSIGNABLE_TYPE,classes=DogConfig.class)) @Configuration public class AnnotationScan { }
当然也可以直接指定有注解的类类型,如UserController.class
使用
public class AnnotationClient2 { public static void main(String[] args) { AnnotationConfigApplicationContext context = new AnnotationConfigApplicationContext(AnnotationScan.class); System.out.println(context.getBean(Car.class)); System.out.println(context.getBean(Cat.class)); System.out.println(context.getBean(Dog.class)); System.out.println(context.getBean(Animal.class)); System.out.println(context.getBean(User.class)); context.close(); } }
3、获取Bean
3.1、根据类型获取
System.out.println(annotationConfigApplicationContext.getBean(MyBean.class));
3.2、根据名称获取
System.out.println(annotationConfigApplicationContext.getBean("createMyBean"));//默认是方法名
注意:默认是1中配置的方法名
也可以再注解Bean中指定:@Bean(name="myBean"),指定后默认方法名不能使用
System.out.println(annotationConfigApplicationContext.getBean("myBean"));// 指定具体名
其中:默认是单例,@Scope("prototype") 非单例了
如1,方法二、展示
System.out.println(annotationConfigApplicationContext.getBean(Jeep.class)); System.out.println(annotationConfigApplicationContext.getBean("createRunnableFactoryBean"));
这个是具体的bean,如何获取工程bean
System.out.println(annotationConfigApplicationContext.getBean(RunnableFactoryBean.class));//类型获取 System.out.println(annotationConfigApplicationContext.getBean("&createRunnableFactoryBean"));//名称获取
&能获取原因:AnnotationConfigApplicationContext→GenericApplicationContext→AbstractApplicationContext→
ConfigurableApplicationContext→ApplicationContext→ListableBeanFactory→BeanFactory
三、基于注解的开发bean,Bean初始化销毁
1、初始化实现InitializingBean,销毁实现DisposableBean
public class Cat implements InitializingBean,DisposableBean{ @Override public void afterPropertiesSet() throws Exception { System.out.println("----------afterPropertiesSet--------"); } @Override public void destroy() throws Exception { System.out.println("----------destroy--------"); } }
2、注入时候实现,
在类中顶一个init,destory,在Config配置中@Bean配置;
@Bean(initMethod="init",destroyMethod="destory") public Dog createDog() { return new Dog(); }
3、使用java中,jsr250提供的注解,@PostConstruct,@PreDestroy
public class Animal { @PostConstruct public void initial() { System.out.println("--------initial------"); } @PreDestroy public void close() { System.out.println("--------close------"); } }
四、Bean装配,注解
1、使用@Component注解,没有明确角色
在class 上增加@Component注解,在AnnotationConfigApplicationContext,参数中添加即可。
AnnotationConfigApplicationContext annotationConfigApplicationContext = new AnnotationConfigApplicationContext( MyConfig.class,User.class);
使用即可。注意:没法绑定初始化方法等。
System.out.println(annotationConfigApplicationContext.getBean(User.class)); System.out.println(annotationConfigApplicationContext.getBean("user"));
可以通过getBeansOfType获取类型Map
System.out.println(annotationConfigApplicationContext.getBeansOfType(User.class));
{user=com.lhx.spring.spring.User@5e57643e}
如果在通过Config注入,那么获取时候不能使用类型获取了,有多个不知道创建那个,可以使用名称获取
2、可以使用其他注解
@Repository 一般用在数据访问层
@Service 一般用在Service层
@Controller 一般用在控制层
五、Bean依赖注入
5.1、Spring方式,@Autowired
@Autowired private UserDao userDao;
如果有多个
1、名称方式,可以使用getBeansOfType获取名称,然后指定名称注入
@Autowired @Qualifier("userDao") private UserDao userDao;
2、在其中某个增加@Primary,默认就会找这个。
5.2、jsr 250 方式,@Resource
5.3、jsr 330方式,@Inject
<dependency> <groupId>javax.inject</groupId> <artifactId>javax.inject</artifactId> <version>1</version> </dependency>