spring注解详解

@PropertySource

用来将properties文件中的K/V值加入到运行时变量中

@PropertySource(value = {"classpath:/person.properties"})

@Scope

	@Bean
    @Scope("singleton")//单例模式
    public Car car(){
        return new Car();
    }

@ComponentScan

会扫描该类所在的包及其子包的所有类,条件匹配则加入ioc容器中,默认将带注解的类加入到ioc容器中

可以定义多个@Filter规则

1.基本用法

1.当没有指定ComponentScan注解的扫描规则,就会以扫描该配置类所在的包及其子包,来完成组件的注册
在这里插入图片描述
在这里插入图片描述

2.扫描要注入的组件,扫描@Component,@Controller,@service,和@Repository

等同于xml中的 <context:component-scan base-package="com.atguigu">
package com.zhw.bean.config;

@Configuration
@ComponentScan(value={"com.zhw"},excludeFilters = {@Filter(type = FilterType.ANNOTATION,classes = { Service.class})})
//includeFilters:只包含的内容
@ComponentScan(value={"com.zhw"},includeFilters = {@Filter(type = FilterType.ANNOTATION,classes = {Controller.class})},useDefaultFilters = false)
//value:指定要扫描的包
//excludeFilters:要排除的内容 type = FilterType.ANNOTATION 按照什么规则排除,注解 classes = {Controller.class, Service.class} 排除哪些注解
public class BeansConfig {

}

2.自定规则

package com.zhw.bean.config;


import java.io.IOException;

public class MyTypeFilter implements TypeFilter {
    /**
     * 当扫到每一个类都会执行该类的match方法
     * @param metadataReader 读取到的当前正在扫描的类的信息
     * @param metadataReaderFactory 可以获取到其他任何类信息的
     * @return
     * @throws IOException
     */
    @Override
    public boolean match(MetadataReader metadataReader, MetadataReaderFactory metadataReaderFactory) throws IOException {
        //获取当亲类注解的信息
        AnnotationMetadata annotationMetadata = metadataReader.getAnnotationMetadata();
        //获取当前正在扫描的类的类信息
        ClassMetadata classMetadata = metadataReader.getClassMetadata();
        //获取当前类资源(类路径)
        Resource resource = metadataReader.getResource();
        String className = classMetadata.getClassName();
        System.out.println("--->"+className);
        if (className.contains("Dao")){
            return true;
        }
        return false;
    }
}

package com.zhw.bean.config;


@Configuration

//会扫描com.zhw包下的所有组件类,只注册满足要求的类
@ComponentScans(value = {
        @ComponentScan(value={"com.zhw"},includeFilters = {
                @Filter(type = FilterType.CUSTOM,classes = {MyTypeFilter.class})
        },
                useDefaultFilters = false)})
@Repository
public class BeansConfig {

}

componentScan会扫描所指定的包以及子包的所有类,按照所给定的规则进行注入

3.@ComponentScans

可以定义多个@ComponentScan

package com.zhw.bean.config;


@Configuration
@ComponentScans({@ComponentScan(basePackages = {"com.zhw.bean.book"})})
public class MainConfigOfAutowired {


    @Primary
    @Bean("bookDaoImpl2")
    public BookDaoImpl bookDaoImpl(){
        return new BookDaoImpl("2");
    }
}

1.懒加载 @Lazy

​ 对于单实例的bean,默认在容器启动的时候创建对象,

懒加载:容器启动不创建对象。第一次使用(获取)Bean创建对象,并初始化

在这里插入图片描述

在这里插入图片描述

2.@Configuration

说明该类是一个配置类,等同于 一个xml文件

package com.zhw.bean.config;

import com.zhw.bean.entities.Person;
import com.zhw.bean.service.PersonService;
import org.springframework.context.annotation.*;
import org.springframework.stereotype.Controller;
import org.springframework.stereotype.Service;

@Configuration
//@ComponentScan(value={"com.zhw"},excludeFilters = {@ComponentScan.Filter(type = FilterType.ANNOTATION,classes = { Service.class})})
//@ComponentScan(value={"com.zhw"},includeFilters = {@ComponentScan.Filter(type = FilterType.ANNOTATION,classes = {Controller.class})},useDefaultFilters = false)
//value:指定要扫描的包
//excludeFilters:要排除的内容 type = FilterType.ANNOTATION 按照什么规则排除,注解 classes = {Controller.class, Service.class} 排除哪些注解
@ComponentScans(value = {
        @ComponentScan(value={"com.zhw"},includeFilters = {
//                @ComponentScan.Filter(type = FilterType.ANNOTATION,classes = {Controller.class}),
//                @ComponentScan.Filter(type = FilterType.ASSIGNABLE_TYPE,classes = {PersonService.class}),
                @ComponentScan.Filter(type = FilterType.CUSTOM,classes = {MyTypeFilter.class})

        },
                useDefaultFilters = false)})
public class BeansConfig {

}

3.按条件装配 @Condition

我把你加入到容器中,但是如果该类有一个@Condition注解则需要满足我的条件我才会注入

@Conditional:按照一定的条件进行判断,满足条件给容器中注册bean,可以用在方法和类上

    @Bean("bill")    @Conditional({WindowsCondition.class})    public Person person01() {        return new Person("bill",62);    }    @Bean("linus")    @Conditional(value = {LinuxCondition.class})    public Person person02() {        return new Person("linus",46);    }

需要出入Condition的实现类

/** * 判断是否是linux系统 */
public class LinuxCondition implements Condition {
    @Override    
	public boolean matches(ConditionContext conditionContext,
	 AnnotatedTypeMetadata annotatedTypeMetadata) {
        Environment environment = conditionContext.getEnvironment();
        String property = environment.getProperty("os.name");
        if (property.contains("linux")){  
             return true;        
        }        
        return false;    
   }
}
package com.zhw.bean.condition;
public class WindowsCondition implements Condition {
    /**     
    * 判断是否windows系统     
    * @param conditionContext 判断条件能使用的上下文环境     
    * @param annotatedTypeMetadata 注释信息     
    * @return     
    * */    
    * @Override    
    * public boolean matches(ConditionContext conditionContext, AnnotatedTypeMetadata annotatedTypeMetadata) 
      //1.获取到ioc使用的beanfactory   
      ConfigurableListableBeanFactory beanFactory = conditionContext.getBeanFactory();
      //2.获取类加载器        
      ClassLoader classLoader = conditionContext.getClassLoader();        
      //3.获取当前的环境信息        
      Environment environment = conditionContext.getEnvironment();        
      //4.获取到bean定义的注册类,可以用他的方法注册,删除,查询bean的定义        
      BeanDefinitionRegistry registry = conditionContext.getRegistry();        
      String property = environment.getProperty("os.name");        
      //判断容器中是否包含某个组件        
      boolean zsh = registry.containsBeanDefinition("zsh");        
      if (property.contains("Windows") ){            
      return true;        
      }        
      return false;    
   }
 }

在这里插入图片描述

package com.zhw.bean.config;import com.zhw.bean.condition.LinuxCondition;import com.zhw.bean.condition.WindowsCondition;import com.zhw.bean.entities.Person;import com.zhw.bean.entities.Student;import org.springframework.context.annotation.*;@Configuration@Conditional(value = {WindowsCondition.class}) //满足这个条件,这个类中配置的所有bean注册才能生效public class MainConfig {    //懒加载    @Bean    @Lazy    public Person person() {        return new Person("bil",62);    }    @Bean("bill")    @Conditional({WindowsCondition.class})    public Person person01() {        return new Person("bill",62);    }    @Bean("linus")    @Conditional(value = {LinuxCondition.class})    public Person person02() {        return new Person("linus",46);    }    @Bean("zsh")    public Student studnt() {        return new Student("12","zsh");    }}

4.@Import

给容器中注册组件

​ 1).包扫描+组件注解标注(@Controller/@Service/@Repository/@Component)

​ 2).@Bean[导入的第三方包里面的组件]

​ 3).@Import快速给容器中导入组件

1.基础用法

直接写这个组件的class类型(要导入的组件),容器中就会自动注册这个组件,id默认为全类名

@Configuration
@Import(value = {Student.class,Person.class})
public class MainConfig2 {}

在这里插入图片描述

2.高级用法@ImportSelector

ImportSelector:返回需要导入组件的全类名

定义引导类    
package com.zhw.bean.condition;
/** 
 * 返回值就是要导入的组件 
 **/
 public class MySelectImports implements ImportSelector {
     /**     
     * @param annotationMetadata 当前标注@Import注解的类的所有注解信息     
     * @return 返回的是类的全限定名,就会注入到ioc容器中     
     */    
     @Override    
     public String[] selectImports(AnnotationMetadata annotationMetadata) {        
     //用        
     //annotationMetadata.        
     //方法可以返回空数组,但是不能是null        
     String[] strings = new String[3];        
     strings[0] = "com.zhw.bean.entities.Color"; 
            return strings;    
    }
  }
package com.zhw.bean.config;
@Configuration
@Import(value = {Student.class,Person.class,MySelectImports.class})
public class MainConfig2 {}

3.@ImportBeanDefinitionRegistrar

@ImportBeanDefinitionRegistrar

//定义实现类
public class MyImportBeanDefinitionRegistrar implements ImportBeanDefinitionRegistrar {    
/**     
*     
* @param annotationMetadata 可以获取标注import的所有注解信息     * @param beanDefinitionRegistry BeanDefinition注册类     
*    把所有需要添加到容器中的bean,可以调用beanDefinitionRegistry的方法     
*/    
	@Override    
	public void registerBeanDefinitions(AnnotationMetadata annotationMetadata, BeanDefinitionRegistry beanDefinitionRegistry) {        
	//获取容器中的Student        
	boolean student = beanDefinitionRegistry.containsBeanDefinition("com.zhw.bean.entities.Student");        
	//获取容器中的Person        
	boolean person = beanDefinitionRegistry.containsBeanDefinition("com.zhw.bean.entities.Person");        
		if (student && person) {            
		//定义bean的信息            
		RootBeanDefinition rootBeanDefinition = new RootBeanDefinition(Yelloow.class);          	
		//参数一:bean的id            
		beanDefinitionRegistry.registerBeanDefinition("Yellow",rootBeanDefinition);        
		}    
	}
}
//引入
package com.zhw.bean.config;
@Configuration@Import(value = {Student.class,Person.class,MyImportBeanDefinitionRegistrar.class})
public class MainConfig2 {}

结果:

在这里插入图片描述

5.FactoryBean(工厂bean)

1.定义factory工厂

package com.zhw.bean.config;
import com.zhw.bean.entities.Color;
import org.springframework.beans.factory.FactoryBean;
//创建一个Spring定义的FactoryBean
public class ColorFactoryBean implements FactoryBean {    
	//返回一个Color对象,这个对象会添加到容器中    
	@Override    
	public Object getObject() throws Exception {        
		return new Color();    
	}    
	//返回对象的类型    
	@Override    
	public Class<?> getObjectType() {        
		return Color.class;    
	}    
	/**     
	* 设置是否是单实例     
	* @return true 单实例 ,false 多实例     
	*/    
	@Override    
	public boolean isSingleton() {        
		return true;    
	}
}

2.引入factorybean工厂

package com.zhw.bean.config;import com.zhw.bean.entities.Color;import com.zhw.bean.entities.Person;import com.zhw.bean.entities.Student;import org.springframework.context.annotation.Configuration;import org.springframework.context.annotation.Import;@Configuration@Import({ColorFactoryBean.class})public class MainConfig3 {}

3.测试

 @Test    @SuppressWarnings("resource")    public void Test05() {        seeBeans();        Object bean1 = app.getBean("com.zhw.bean.config.ColorFactoryBean");        Object bean2 = app.getBean("com.zhw.bean.config.ColorFactoryBean");        System.out.println(bean1.getClass());        //获取factorybean工厂        Object bean = app.getBean("&com.zhw.bean.config.ColorFactoryBean");        System.out.println(bean+"工厂bean");        //多实例        System.out.println(bean1 == bean2);    }    

4.结果

在这里插入图片描述

5.注意

工厂类其实质是Color对象,拿到factorybean对象是加一个前缀“&”就得到啦

6.bean生命周期

1.用@Bean注解指定初始化和销毁方法

bean创建–>初始化–>销毁过程

package com.zhw.bean.config;import com.zhw.bean.entities.Car;import org.springframework.context.annotation.Bean;import org.springframework.context.annotation.Configuration;import org.springframework.context.annotation.Import;import org.springframework.context.annotation.Scope;/** *  bean的生命周期 *   bean创建-->初始化 -->销毁 *   容器管理单实例bean的生命周期: *      可以自定义初始化和销毁方法,容器在bean进行到当前生命周期的时候来调用我们自定义的初始化和销毁方法 *   构造(对象创建) *      单实例:在容器启动的时候创建 *      多实例:在每次获取的时候创建对象 *   初始化: *      对象创建完成,并赋值好,调用初始化方法。。。 *   销毁: *      容器关闭的时候,执行销毁的方法 * *   1).指定初始化和销毁的方法 *      init-method和destory-method */@Configurationpublic class MainConfigOfLifeCycle {    @Bean(initMethod = "init",destroyMethod = "destory")    @Scope("singleton")    public Car car() {        return new Car();    }}

在这里插入图片描述

对于多实例的bean,只有获取该bean的时候才会创建,执行其初始化的方法,并且容器关闭也不会执行销毁方法

2.通过让Bean实现接口指定初始化和销毁方法

@Componentpublic class Cat implements InitializingBean, DisposableBean {    public Cat() {        System.out.println("constructor...cat...");    }    //销毁方法    @Override    public void destroy() throws Exception {        System.out.println("cat...destory");    }    //初始化方法    @Override    public void afterPropertiesSet() throws Exception {        System.out.println("cat...init");    }}

在这里插入图片描述

3.使用JSR250

1.@PostConstruct:在bean创建完成并且属性赋值完成,执行初始化
2.@PreDestory:在bean在容器销毁之前
package com.zhw.bean.entities;import javax.annotation.PostConstruct;import javax.annotation.PreDestroy;@Component //加入到容器中public class Dog {    public Dog() {        System.out.println("dog..constructor..");    }    //对象创建 的方法    @PostConstruct    public void init() {        System.out.println("PostConstructor...");    }    //对象在容器关闭之前的方法    @PreDestroy    public void destory() {        System.out.println("PreDestory...");    }}

4.BeanPostProcessor-后置处理器

针对组件中的所有组件的初始化前后

在bean初始化前后处理一些工作:

package com.zhw.bean.entities;import org.springframework.beans.BeansException;import org.springframework.beans.factory.config.BeanPostProcessor;public class MyBeanPostProcessor implements BeanPostProcessor {    public MyBeanPostProcessor() {        System.out.println("constructor...");    }    /**     *  在初始化之前工作     * @param o bean对象     * @param s bean的名字     * @return     * @throws BeansException     */    @Override    public Object postProcessBeforeInitialization(Object o, String s) throws BeansException {        System.out.println("postProcessBeforeInitialization"+s+o+"初始化之前");        return o;    }    /**     * 在初始化之后工作     * @param o     * @param s     * @return     * @throws BeansException     */    @Override    public Object postProcessAfterInitialization(Object o, String s) throws BeansException {        System.out.println("postProcessAfterInitialization"+s+o+"初始化之后");        return o;    }}

在这里插入图片描述

属性赋值相关的注解

1.@value:在实体类中写

1.写配置文件

2.引入配置文件

3.用@Value(${“”})

person.nickNmae=小刺老
package com.zhw.bean.config;@Configuration//使用@PropertySource读取外部配置文件中的k/v值保存到运行的环境变量,加载完外部的配置文件以后使用${}取出配置文件的值@PropertySource(value = {"classpath:/person.properties"})public class MainConfigOfProperty {    @Bean    public Person person() {        return new Person();    }}
@Data@NoArgsConstructor@AllArgsConstructorpublic class Person {    //使用@Value赋值    //1.基本数值    //2.可以写SpEL,#{}    //3.可以写${},取出配置文件的值(在运行环境变量里面的值)    @Value("张三")    private String name;    @Value("#{10*2}")    private Integer age;    @Value("${person.nickName}")    private String nickName;}
    //属性相关的注解测试//可以使用app获取运行数据    @Test    @SuppressWarnings("resource")    public void Test07() {        seeBeans();        Person bean = app.getBean(Person.class);        System.out.println(bean);        ConfigurableEnvironment environment = app.getEnvironment();        String property = environment.getProperty("person.nickName");        Map<String, Object> systemProperties = environment.getSystemProperties();                        systemProperties.forEach((S,O) -> System.out.println(S + O));    }

自动装配

1.@AutoWired

Controller注入Service,Service注入Dao,

1).@Autowired:自动注入按照类型注入

​ 优先按照类型去容器中找对应的组件:app.getBean(BookDao.class)

@Servicepublic class BookServiceImpl implements BookService {    @Autowired    private BookDao bookDao;}当像容器内其中注入多个相同类型的组件时会报错,注入时会报错,可以使用@Primary注解指定当冲突的时候优先使用带有@primary注解的类

@AutoWired不仅可以标注在属性上,话可以构造器,参数,方法上

1.标注在方法位置上

package com.zhw.bean.boos;@Componentpublic class Boos {    private Car car;    public Car getCar() {        return car;    }    @Autowired    //标注在,spring容器创建当前对象,就会调用方法,完成赋值    //方法使用的参数,从ioc容器中获取    public void setCar(Car car) {        this.car = car;    }}
package com.zhw.bean.boos;import org.springframework.stereotype.Component;@Componentpublic class Car {}
 @Test    public void test07() {//       see2();        Boos bean = app2.getBean(Boos.class);        Car car = bean.getCar();        Car bean1 = app2.getBean(Car.class);        System.out.println(bean1);        System.out.println(car);    }

在这里插入图片描述

2.标注在有参构造器上

package com.zhw.bean.boos;import org.springframework.beans.factory.annotation.Autowired;import org.springframework.stereotype.Component;//默认加载ioc容器中的组件,容器启动会调用组建的无参构造器创建对象,在进行初始化赋值等操作,也就是说,容器一启动,就会创建容器中包含的所有组件@Componentpublic class Boos {    private Car car;    public Car getCar() {        return car;    }    //当容器启动调用,有参构造器方法,并且找到从容器中找Car组件,并且注入    @Autowired    public Boos(Car car){        this.car = car;    }    public void setCar(Car car) {        this.car = car;    }}

3.标注在参数上

package com.zhw.bean.boos;@Componentpublic class Boos {    private Car car;    public Car getCar() {        return car;    }    //从容器中获组件,如果组件只有一个有参构造器,这个有参构造器的@Autowired可以省略,参数位置的组件还是会从容器中获取    public Boos(@Autowired Car car){        this.car = car;    }    public void setCar(Car car) {        this.car = car;    }}
@Bean//会从容器中获取carpublic Boos boos( @Autowired Car car ) {    Color color = new Color();    color.setCar(car);    return color;}

其本质就是根据类型,从容器中找到指定的组件注入

2.@Qualifier(“name”)

@Qualifier:按照名称 注入,需要结合@Autowired使用

@Service@Datapublic class BookServiceImpl implements BookService {    @Autowired //按照类型注入,有多个类型相同会报错    @Qualifier("bookDaoImpl2") //按照名称注入    private BookDaoImpl bookDaoImpl2;    @Override    public void print(){        System.out.println(bookDaoImpl2);    }}
@Service@Datapublic class BookServiceImpl implements BookService {    	//按照id当required = false时没有找到也不会报错    @Autowired(required = false)     @Qualifier("bookDaoImpl2")    private BookDaoImpl bookDaoImpl2;    @Override    public void print(){        System.out.println(bookDaoImpl2);    }}

3.@Primary

让Spring进行自动装配的时候,默认使用首选的bean

//容器中可能有多个相同类型的bean,首先使用带有@Primary注解的bean@Configuration@ComponentScans({@ComponentScan(basePackages = {"com.zhw.bean.book"})})public class MainConfigOfAutowired {    @Primary    @Bean("bookDaoImpl2")    public BookDaoImpl bookDaoImpl(){        return new BookDaoImpl("2");    }}
@Test    public void test05() {        BookServiceImpl bookService = app.getBean(BookServiceImpl.class);        BookDaoImpl bookDaoImpl2 = bookService.getBookDaoImpl2();        System.out.println(bookDaoImpl2.getLable());    }
@Repositorypublic class BookDaoImpl implements BookDao {    public BookDaoImpl() {    }    public BookDaoImpl(String lable) {        this.lable = lable;    }    private String lable = "1";    public String getLable() {        return lable;    }    public void setLable(String lable) {        this.lable = lable;    }}

在这里插入图片描述

注入了带有@primary注解的bean

4.@Resource(JSR250)[java规范的注解]

@Resource:java规范和@AutoWired一样默认按照属性的名臣装配的

@Service@Datapublic class BookServiceImpl implements BookService {//    @Autowired(required = false) //按照类型注入,有多个类型相同会报错//    @Qualifier("bookDaoImpl2")//    private BookDaoImpl bookDaoImpl2;//    @Autowired //按照类型注入,有多个类型相同会报错    @Resource(name = "bookDao",type = BookDao.class")    private BookDaoImpl bookDaoImpl;    //注入指定名称的bean 找不到会报错    @Resource(name = "bookDaoImpl2")    private BookDaoImpl bookDaoImpl;    @Override    public void print(){        System.out.println(bookDaoImpl);    }}

在这里插入图片描述

1.找不到bean name=""会报错

5.@Inject(JSR250)[java规范的注解]

1.@Autowried一样保留@Primary的特性@Service@Datapublic class BookServiceImpl implements BookService {//    @Autowired(required = false) //按照类型注入,有多个类型相同会报错//    @Qualifier("bookDaoImpl2")//    private BookDaoImpl bookDaoImpl2;//    @Autowired //按照类型注入,有多个类型相同会报错//    @Resource(name = "bookDaoImpl2")    @Inject    private BookDaoImpl bookDaoImpl;    @Override    public void print(){        System.out.println(bookDaoImpl);    }}

需要导入@inject的jar包

 <dependency>     <groupId>javax.inject</groupId>     <artifactId>javax.inject</artifactId>     <version>1</version> </dependency>

6.自定义组件使用Spring容器底层的组件

自定义组件实现xxxAware:在创建对象的时候,会调用接口规定的方法注入相关的组件,把spring底层一些组件注入到自定i的Bean中;

xxxAware:功能使用XXXProcessor;

​ ApplicationContextAware ==> ApplicationContextAwareProcessor

package com.zhw.bean.component;@Componentpublic class Component1 implements ApplicationContextAware, BeanNameAware, EmbeddedValueResolverAware {    private ApplicationContext applicationContext;    public ApplicationContext getApplicationContext() {        return applicationContext;    }    //设置ioc容器对象    @Override    public void setApplicationContext(ApplicationContext applicationContext) throws BeansException {        System.out.println("传入的ioc:"+applicationContext);        this.applicationContext = applicationContext;    }    //当前组件的名称id    @Override    public void setBeanName(String s) {        System.out.println("当前bean的名字'':\""+s);    }    @Override    public void setEmbeddedValueResolver(StringValueResolver resolver) {        String s = resolver.resolveStringValue("你好${os.name},我是#{20*10}");        System.out.println(s);    }}
@Testpublic void test() {   Component1 component =   app.getBean(Component1.class);   ApplicationContext app =  component.getApplicationContext();}

@Profile

1.spring为我们提供的可以根据当前环境,动态的切换和激活一系列组件的功能

2.指定组件在哪个环境的情况下才能被注册到容器中,不指定,任何环境下都能注册这个组件

3.加了环境标识,只有该环境激活了才注入,默认是default环境

package com.zhw.bean.config;@Configuration@PropertySource("classpath:/db.properties")public class MainConfigOfProfile implements EmbeddedValueResolverAware {    @Value("${jdbc.url}")    private String url;    @Value("${jdbc.password}")    private String password;    @Value("${jdbc.user}")    private String user;    private String driver;    private StringValueResolver resolver;    @Profile("test")    @Bean("TestDataSource")    public DataSource dataSourceTest() throws PropertyVetoException {        ComboPooledDataSource dataSource = new ComboPooledDataSource();        dataSource.setUser(user);        dataSource.setPassword(password);        dataSource.setJdbcUrl(url);        dataSource.setDriverClass(driver);        return dataSource;    }    @Bean    @Profile("test")    public Car car(){        return new Car();    }    //默认环境,不加也是默认环境    @Profile("default")    @Bean("DefaultDataSource")    public DataSource dataSourceDefault() throws PropertyVetoException {        ComboPooledDataSource dataSource = new ComboPooledDataSource();        dataSource.setUser(user);        dataSource.setPassword(password);        dataSource.setJdbcUrl(url);        dataSource.setDriverClass(driver);        return dataSource;    }    @Profile("dev")    @Bean("DevDataSource")    public DataSource dataSourceDev() throws PropertyVetoException {        ComboPooledDataSource dataSource = new ComboPooledDataSource();        dataSource.setUser(user);        dataSource.setPassword(password);        dataSource.setJdbcUrl(url);        dataSource.setDriverClass(driver);        return dataSource;    }    @Profile("pro")    @Bean("ProDataSource")    public DataSource dataSourcePro() throws PropertyVetoException {        ComboPooledDataSource dataSource = new ComboPooledDataSource();        dataSource.setUser(user);        dataSource.setPassword(password);        dataSource.setJdbcUrl(url);        dataSource.setDriverClass(driver);        return dataSource;    }    @Override    public void setEmbeddedValueResolver(StringValueResolver resolver) {        this.resolver = resolver;        this.driver = resolver.resolveStringValue("${jdbc.driver}");    }}

1.使用代码的方式指定环境

package com.zhw.test;public class IOCTest_Profile {    @Test    public void test01(){        //创建ApplicationContext对象        AnnotationConfigApplicationContext app = new AnnotationConfigApplicationContext();        //设置需要激活的环境        app.getEnvironment().setActiveProfiles("test","dev");        //注册主配置类        app.register(MainConfigOfProfile.class);		//刷新容器        app.refresh();        String[] beanDefinitionNames = app.getBeanDefinitionNames();        for (String beanDefinitionName : beanDefinitionNames) {            System.out.println(beanDefinitionName);        }    }}

在这里插入图片描述

2.写在类上

package com.zhw.bean.config;@Configuration@PropertySource("classpath:/db.properties")@Profile("pro") //只有是指定的环境才会加载该配置类public class MainConfigOfProfile implements EmbeddedValueResolverAware {    @Value("${jdbc.url}")    private String url;    @Value("${jdbc.password}")    private String password;    @Value("${jdbc.user}")    private String user;    private String driver;    private StringValueResolver resolver;    @Profile("test")    @Bean("TestDataSource")    public DataSource dataSourceTest() throws PropertyVetoException {        ComboPooledDataSource dataSource = new ComboPooledDataSource();        dataSource.setUser(user);        dataSource.setPassword(password);        dataSource.setJdbcUrl(url);        dataSource.setDriverClass(driver);        return dataSource;    }    @Bean    @Profile("test")    public Car car(){        return new Car();    }    //默认环境,不加也是默认环境    @Profile("default")    @Bean("DefaultDataSource")    public DataSource dataSourceDefault() throws PropertyVetoException {        ComboPooledDataSource dataSource = new ComboPooledDataSource();        dataSource.setUser(user);        dataSource.setPassword(password);        dataSource.setJdbcUrl(url);        dataSource.setDriverClass(driver);        return dataSource;    }    @Profile("dev")    @Bean("DevDataSource")    public DataSource dataSourceDev() throws PropertyVetoException {        ComboPooledDataSource dataSource = new ComboPooledDataSource();        dataSource.setUser(user);        dataSource.setPassword(password);        dataSource.setJdbcUrl(url);        dataSource.setDriverClass(driver);        return dataSource;    }    @Profile("pro")    @Bean("ProDataSource")    public DataSource dataSourcePro() throws PropertyVetoException {        ComboPooledDataSource dataSource = new ComboPooledDataSource();        dataSource.setUser(user);        dataSource.setPassword(password);        dataSource.setJdbcUrl(url);        dataSource.setDriverClass(driver);        return dataSource;    }    @Override    public void setEmbeddedValueResolver(StringValueResolver resolver) {        this.resolver = resolver;        this.driver = resolver.resolveStringValue("${jdbc.driver}");    }}

注意点:

​ 没有标识环境的Bean在任何环境下都是加载的

AOP[动态代理]

1.使用

值在程序运行期间动态的将某段代码切入到指定方法指定位置进行运行的变成方式:

1.目标类

package com.zhw.aop;public class MathCalculator {    public int div(int x,int y){        return  x/y;    }}

2.切面类

package com.zhw.aop;import org.aspectj.lang.JoinPoint;import org.aspectj.lang.annotation.*;import java.util.Arrays;import java.util.List;@Aspectpublic class LogAspects {    //抽入公共的切入点表达式    //1. 本类引用    @Pointcut("execution(public int  com.zhw.aop.MathCalculator.*(..))")    public void pointCut(){};// @Before在目标方法之前切入,切入点表达式(指定在哪个方法切入)    @Before("pointCut()")    public void logStart(JoinPoint joinPoint){        Object[] args = joinPoint.getArgs();        List<Object> objects = Arrays.asList(args);        System.out.println(""+joinPoint.getSignature().getName()+"运行。。。@Before:参数列表是:{"+objects+"}");    }    @After("pointCut()")    public void logEnd(JoinPoint joinPoint){        System.out.println(""+joinPoint.getSignature().getName()+"结束");    }    @AfterReturning(value = "pointCut()",returning = "result")    public void logReturn(Object result){ //封装返回值        System.out.println("方法正常返回。。运行结果:{"+result+"}");    }    @AfterThrowing(value = "pointCut()",throwing = "e")    public void logException(JoinPoint joinPoint,Exception e) { //封装异常 JoinPoint必须写在参数的第一个位置        System.out.println("除法异常。。。异常信息:{"+e.getLocalizedMessage()+"}");    }}

3.配置类

package com.zhw.aop;@EnableAspectJAutoProxy // 一定要开启注解的AOP@Configurationpublic class MainConfigOfAOP {    //目标类    @Bean    public MathCalculator calculator(){        return new MathCalculator();    }    //切面类    @Bean    public LogAspects aspects(){        return new LogAspects();    }}

步骤

​ 1.写业务类

​ 2.写切面类

​ 3.加入到容器

​ 4.开启注解AOP

​ 5.测试

2.原理

1.@EnableAspectJAutoProxy

package org.springframework.context.annotation;@Target(ElementType.TYPE)@Retention(RetentionPolicy.RUNTIME)@Documented@Import(AspectJAutoProxyRegistrar.class) //导入组件,利用AspectJAutoProxyRegistrar自定义给容器中注册beanpublic @interface EnableAspectJAutoProxy {	boolean proxyTargetClass() default false;	boolean exposeProxy() default false;}
1 Spring基本特征 6 2 Spring的组成 6 2.1 Spring的jar包 6 2.2 Spring配置文件 7 2.3 Spring API 8 3 Spring基本功能详解 8 3.1 SpringIOC 8 3.2别名Alias 11 别名拓展: 11 3.3 Spring容器内部对象的创建 12 Spring容器内部对象创建拓展: 12 3.3.1使用类构造器实例化(默认无参数) 14 3.3.2使用静态工厂方法实例化(简单工厂模式) 14 3.3.3初始化(创建)bean时机 15 Lazy-init初始化bean的时机拓展: 15 3.4 Bean的作用域 16 Scope单例多例作用域拓展: 16 3.4.1 singleton(默认值) 16 3.4.2 prototype 17 3.4.3 Request 17 3.4.4 Session 18 3.4.5 Global session 18 3.4.6 指定Bean的初始化方法和销毁方法 18 Bean的初始化和销毁拓展: 18 Spring的IOC总结: 20 3.5 依赖注入(DI) 20 3.5.1 使用构造器注入 20 3.5.2 使用属性setting方法进行注入 21 3.5.3 装配list集合 22 3.5.4 装配set集合 22 3.5.5 装配map 22 3.5.6 装配Properties 23 3.6 注解注入 23 注解注入拓展: 23 3.6.1 @Autowired 26 3.6.2 @Qualifier 27 3.6.3 @Resource 27 3.6.4 @PostConstruct 28 3.6.5 @PreDestroy 28 注解注入拓展: 28 3.7扫描注入 30 注解扫描拓展: 32 Mvc用注解写: 34 Spring容器IOC和di的整个启动过程: 38 3.8 spring中的继承 38 拓展spring为类中的属性赋值: 40 小结: 47 面向接口编程: 47 4 面向切面编程 52 4.1 代理模式 52 代理模式拓展: 52 4.1.1 JDK动态代理 58 JDK动态代理拓展: 59 4.1.2 CGLIB做代理 66 CGLIB动态代理拓展: 68 4.1.3 Spring的动态代理 71 4.2 AOP编程 71 4.2.1概念: 71 SpringAOP概念拓展: 73 之前实现了目标方法的动态调用,现在来实现切面的动态调用。 74 4.2.2 AOP实现的两种模式 78 4.2.2.1 xml形式 78 XML形式拓展: 81 异常通知处理例子: 91 不用spring异常通知,另一种处理异常 96 4.2.2.2Aop注解形式(了解) 99 注解注入拓展: 103 5 Spring数据库 106 5.1 Spring+JDBC 106 5.1.1 Jdbc编程特点 106 5.1.2引入DataSource 106 5.1.3 核心类JdbcTemplate 106 5.1.4 使用JdbcTemplate 106 5.1.5 继承JdbcDaoSupport 107 5.1.6 使用properties文件 107 5.1.7 RowMapper的使用 107 拓展: 108 DataSource注入的三种方式: 108 5.1.8声明式事务管理 116 5.1.8.1Spring的事务管理器 117 5.1.8.2Spring事务的传播属性 117 5.1.8.3Spring事务的隔离级别 117 拓展: 118 5.1.8.4以XML配置的 形式 119 拓展: 120 5.1.8.5以注解方式配置 125 拓展: 127 5.1.9使用CGLIB以XML形式配置事务 130 5.2 Spring+Hibernate 131 5.2.1 HibernateTemplate模板 131 5.2.2 声明式事务 131 配置XML文件 131 拓展: 132 注解形式: 137 拓展: 138 6 Struts2+spring+hibernate 141 6.1 需要添加的jar包 141 6.2 Spring融合web服务器 141 6.3 struts.xml文件 143 6.4 OpenInSessionView 143 拓展: 144 实例: 146
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值