一、用于创建对象
@Component 作用:把当前类对象存入spring容器中 相当于配置文件中的< bean id=“” class=“”/>
属性: value 就是对象的名称,也是bean的id值 value的值是唯一的,创建的对象在整个spring容器中就一个
案例:
@Component(value = “myTeacher”)等同于 其中value可以省略不写(最常用) 也可以只写@Component,由spring提供默认名称:类名的首字母小写,如:该类是Student,那么提供的默认名称是student
衍生:
@Controller:一般用在表现层 @Service:一般用在业务层 @Repository:一般用在持久层 component能做的事情,这三个也能做; 如果不属于三层中的任何一层,我们就用component来创建。 扩展:
@Component 和 @Bean 的区别是什么?
1.作用对象不同: @Component 注解作用于类, @Bean 注解作用于方法 2.@Component 通常是通过路径扫描来自动侦测以及自动装配到 Spring 容器中(我们可以使用 @ComponentScan 注解定义要扫描的路径从中找出标识了需要装配的类自动装配到 Spring 的 bean 容器中)。 @Bean 注解通常是我们在标有该注解的方法中定义产生这个 bean,@Bean 告诉了 Spring 这是某个类的实例,当我们需要用它的时候还给我。 3.@Bean 注解比 @Component 注解的自定义性更强,而且很多地方我们只能通过 @Bean 注解来注册 bean。比如当我们引用第三方库中的类需要装配到 Spring 容器时,只能通过 @Bean 来实现。 案例:
@Configurationpublic
Class AppConfig {
@Bean
public TransferService transferService() {
return new TransferServiceImpl();
}
}
@Componentpublic
Class ServiceImpl implements AService {
...
}
二、用于注入数据
@Autowire 和 @Resource
1.@Autowire,@Resource都可以用来装配bean,都可以用于字段或setter方法。 2.@Autowire 默认按类型装配,默认情况下必须要求依赖对象必须存在,如果要允许 null 值,可以设置它的 required 属性为 false。 3. @Resource 默认按名称装配,当找不到与名称匹配的 bean 时才按照类型进行装配。名称可以通过 name 属性指定,如果没有指定 name 属性,当注解写在字段上时,默认取字段名,当注解写在 setter 方法上时,默认取属性名进行装配。如果 name 属性一旦指定,就只会按照名称进行装配。
案例:
@Autowire和@Qualifier配合使用效果和@Resource一样:
@Autowired(required = false) @Qualifier("example")
private Example example;
@Resource(name = "example")
private Example example;
4.Value
作用:用于注入基本类型和String类型的数据 属性:value用于指定数据的值 它可以使用spring中SpEl(也就是spring的el表达式) SpEl的写法:${表达式}
三、用于改变作用范围
1.Scope 作用: 用于指定bean的作用范围 属性: value指定范围的取值 常用取值 singleton, prototype。 单例模式生命周期与容器相同。
优点:无论获取多少次,返回都是同一个实例,因为每个类只创建一个实例,可以节省内存空间,减少资源浪费。 缺点:可能会引发线程安全问题(如果这个唯一对象上有共享数据,并且有多个线程会同时操作这个共享数 据)
原型模式生命周期,是每次使用时创建新的对象,用完等待垃圾回收器回收。
优点:不会引发线程安全问题(因为每个线程持有的实例是不同的) 缺点:由于每次获取都会创建新的实例,会占用服务器的内存空间,造成资源浪费。
什么时候使用单例和多例?
1)从使用频次上考虑,如果一个对象使用的频率非常高,建议使用单例,这样会将bean对象存储到bean池中,从始至终只有一个实例,可以减少对象创建,减少对资源的消耗。 2)从使用频次上考虑,如果一个对象使用的频率非常低,没有必要将对象存储到map中(存储到bean池中的对象会一直存在bean池中,在spring容器销毁时销毁),建议使用多例。 3)在没有线程安全问题的前提下,没必要每次获取都创建一个对象,建议使用单例,这样子既浪费CPU又浪费内存; 4)如果一个对象被多个线程所共享,并且对象中存在共享数据,一旦这个数据被多个线程所操作,就可能会产生线程不安全问题,可以考虑使用多例
扩展: bean的作用域可以通过scope属性来指定bean的作用域
1、singleton:默认值。当IOC容器一创建就会创建bean的实例,而且是单例的,每次得到同一个。 2、prototype:原型的。当IOC容器一创建不会实例化该bean,每次调用getBean方法时才实例化该bean,而且每次调用都会返回一个新的实例 3、request:每次HTTP请求都会创建一个新的Bean,该作用域仅适用于WebApplicationContext环境 4、session:同一个HTTP Session 共享一个Bean,不同的 HTTP Session 使用不同的Bean. 该作用域仅适用于WebApplicationContext环境。
四、与生命周期有关
1.PostConstruct 作用:用于指定初始化方法 在容器销毁bean之前执行的方法,例如一些清理工作,关流等;
2.PreDestroy 作用:用于指定销毁方法 在bean创建完成并且属性赋值完成之后来执行初始化方法 案例:
public class Dog {
public Dog() {
System.out.println("dog constructor...");
}
@PostConstruct
public void init(){
System.out.println("dog init...");
}
@PreDestroy
public void destroy(){
System.out.println("dog destroy");
}
}
@Configuration
public class MainConfigOfLifeCycle {
@Bean
public Dog dog(){
return new Dog();
}
}
@Test
public void test01(){
AnnotationConfigApplicationContext applicationContext = new AnnotationConfigApplicationContext(MainConfigOfLifeCycle.class);
System.out.println("创建容器完成!");
applicationContext.close();
}
dog constructor...
dog init...
创建容器完成!
dog destroy
五、配置类
1.Configuration 作用: 指定当前类是一个配置类 2.ComponentScan 作用:扫描指定注解的类注册到IOC容器中
@ComponentScan用于类或接口上主要是指定扫描路径,spring会把指定路径下带有指定注解的类注册到IOC容器中。 会被自动装配的注解包括@Controller、@Service、@Component、@Repository等等。 其作用等同于<context:component-scan base-package=“com.maple.learn” />配置。 value: basePackages、value:指定扫描路径,如果为空则以@ComponentScan注解的类所在的包为基本的扫描路径 basePackageClasses:指定具体扫描的类 includeFilters:指定满足Filter条件的类 excludeFilters:指定排除Filter条件的类 includeFilters和excludeFilters 的FilterType可选: FilterType.ANNOTATION:按照注解过滤 FilterType.ASSIGNABLE_TYPE:按照给定的类型过滤 FilterType.ASPECTJ:按照ASPECTJ表达式过滤 FilterType.REGEX:按照正则表达式过滤 FilterType.CUSTOM:按照自定义规则过滤
classes和value属性为过滤器的参数,必须为class数组,类只能为以下三种类型:
ANNOTATION 参数为注解类,如 Controller.class, Service.class, Repository.class ASSIGNABLE_TYPE 参数为类,如 SchoolDao.class ?CUSTOM 参数为实现 TypeFilter 接口的类 ,如 MyTypeFilter.class
案例:
@Configuration@ComponentScan(basePackages= "com.learn",
includeFilters = {@Filter(type = FilterType.ANNOTATION,classes = {Controller.class,Service.class})},useDefaultFilters = false)
public class SpringConfig {}
上面配置只扫描了带有Controller,Service注解的自定义的类: 自定义一个类MyTypeFilter实现TypeFilter接口,这样这个TypeFilter就扫描所有类并只通过类名包含了controller的类,如下:
public class MyTypeFilter implements TypeFilter { @Overridepublic boolean match(MetadataReader metadataReader, MetadataReaderFactory metadataReaderFactory)throws IOException {
经过下面的配置:
@Configuration@ComponentScan(basePackages = "com.learn",
includeFilters = {
@Filter(type = FilterType.ASSIGNABLE_TYPE,classes = {Person.class}),
@Filter(type=FilterType.CUSTOM,classes= {MyTypeFilter.class}),},
useDefaultFilters = false)
public class SpringConfig {}
第一个@Filter通过FilterType.ASSIGNABLE_TYPE规定了只扫描Person类型的类,第二个@Filter通过FilterType.CUSTOM自定义过滤规则规定了只扫描类名包含controller的类。
2.@Bean Spring的@Bean注解用于告诉方法,产生一个Bean对象,然后这个Bean对象交给Spring管理。产生这个Bean对象的方法Spring只会调用一次,随后这个Spring将会将这个Bean对象放在自己的IOC容器中; 案例:
@Configuration
public class AppConfig {
@Bean
public MyBean myBean(){
return new MyBean();
}
@Bean({"b1","b2"})
@Scope("prototype")
public MyBean myBean(){
return new MyBean();
}
@Bean
public MyBean myBeanOne(){
return new MyBean();
}
@Bean
@Primary
public MyBean myBeanTwo(){
return new MyBean();
}
public class MyBean {
public MyBean(){
System.out.println("MyBean Initializing");
}
}
4.PropertySource
作用: 用于加载.properties文件中的配置 属性: value[]:用于指定properties文件位置 如果是在类路径下 需要写上classpath 细节: 必须是从spring容器获取的才能注入 new的对象跟spring没有任何关系
5.EnableTransactionManagement 作用: 配置类开启事务支持 6.EnableAspectJAutoProxy 作用: 配置类开启切面 7.Transaction 作用: 控制事务提交/回滚 作用于类上
Transactional 的作用范围
1.方法 :推荐将注解使用于方法上,不过需要注意的是:该注解只能应用到 public 方法上,否则不生效。 2.类 :如果这个注解使用在类上的话,表明该注解对该类中所有的 public 方法都生效。 3.接口 :不推荐在接口上使用。
@Transactional 的常用配置参数总结:
属性名 说明 propagation 事务的传播行为,默认值为 REQUIRED,可选的值在上面介绍过 isolation 事务的隔离级别,默认值采用 DEFAULT,可选的值在上面介绍过 timeout 事务的超时时间,默认值为-1(不会超时)。如果超过该时间限制但事务还没有完成,则自动回滚事务。 readOnly 指定事务是否为只读事务,默认值为 false。 rollbackFor 用于指定能够触发事务回滚的异常类型,并且可以指定多个异常类型。
8.Aspect 作用: 声明这个类是一个切面类
|