Spring常用注解式开发
1、组件注册@Configuration、@Bean给容器中注册组件。
注解,@Configuration告诉Spring这是一个配置类,相当于bean.xml配置文件。
注解,@Bean给Spring容器注入一个bean对象,bean.xml配置文件里面的class属性,在注解式开发中class类型是返回值的类型,bean.xml配置文件里面的id属性,在注解式开发中id默认是方法名称。
2、组件注册@ComponentScan自动扫描组件、指定扫描规则。
注解,@ComponentScan包扫描注解,只要标注了@Controller、@Service、@Repository、@Component注解组件都会被扫描,然后将对应的bean实例添加到spring容器中。
3、使用maven构建项目,学习Spring的注解开发,如下所示。
<project xmlns="http://maven.apache.org/POM/4.0.0"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0
http://maven.apache.org/xsd/maven-4.0.0.xsd">
<modelVersion>4.0.</modelVersion>
<groupId>com.bie</groupId>
<artifactId>spring-annotation</artifactId>
<version>0.0.-SNAPSHOT</version> <dependencies>
<!-- https://mvnrepository.com/artifact/org.springframework/spring-context -->
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-context</artifactId>
<version>4.3..RELEASE</version>
</dependency>
<!-- https://mvnrepository.com/artifact/org.projectlombok/lombok -->
<dependency>
<groupId>org.projectlombok</groupId>
<artifactId>lombok</artifactId>
<version>1.18.</version>
<scope>provided</scope>
</dependency> </dependencies> </project>
先搞一个实体类,用于数据的传输。
package com.bie.po; import lombok.AllArgsConstructor;
import lombok.Data;
import lombok.NoArgsConstructor; /**
*
*
* @Title: Person.java
* @Package com.bie.po
* @Description: TODO
* @author biehl
* @date 2019年12月9日
* @version V1.0
*
*/
@AllArgsConstructor
@NoArgsConstructor
@Data
public class Person { private Integer id;
private String name; }
组件注册@Configuration、@Bean给容器中注册组件。组件注册@ComponentScan自动扫描组件、指定扫描规则。
package com.bie.config; import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.ComponentScan;
import org.springframework.context.annotation.ComponentScan.Filter;
import org.springframework.context.annotation.Configuration;
import org.springframework.context.annotation.FilterType;
import org.springframework.stereotype.Repository; import com.bie.filter.PersonCustomFilter;
import com.bie.po.Person; /**
*
*
* @Title: SpringApplicationConfig.java
* @Package com.bie.config
* @Description: TODO
* @author biehl
* @date 2019年12月9日
* @version V1.0
*
*
* 1、组件注册@Configuration、@Bean给容器中注册组件。
*
* 2、组件注册@ComponentScan自动扫描组件、指定扫描规则
*
*/
// @Configuration告诉Spring这是一个配置类,相当于bean.xml配置文件。
@Configuration // @ComponentScan,只要标注了@Controller、@Service、@Repository、@Component注解组件都会被扫描,然后将对应的bean实例添加到spring容器中。
// jdk1.8版本的时候,@ComponentScan新增了@Repeatable,可以写多次@ComponentScan注解。
// value属性值指定了要扫描的包。
// excludeFilters属性值是Filter[]数组。Filter数组是一个@Filter注解。指定扫描的时候按照什么规则排除那些组件。
// includeFilter属性值是只包含。Filter[]。Filter数组是一个@Filter注解。指定扫描的时候只需要包含那些组件。
@ComponentScan(value = "com.bie", // excludeFilters排除的规则。
excludeFilters = { // @Filter注解进行排除要扫描的包
// type属性排除的规则,ANNOTATION按照注解排除、ASSIGNABLE_TYPE按照给定的类型排除、ASPECTJ表达式排除、REGEX正则表达式排除、CUSTOM自定义排除。
// classes属性是按照类进行排除。
@Filter(type = FilterType.ANNOTATION, classes = { Repository.class }) }, // includeFilter只包含规则。includeFilters需要useDefaultFilters配合使用。
includeFilters = { // @Filter(type = FilterType.ANNOTATION, classes = { Service.class }),
// ASSIGNABLE_TYPE按照给的的类型进行包含,比如只要是PersonDao类型的组件都会加载到容器中,不管是子类还是实现类等等。
// @Filter(type = FilterType.ASSIGNABLE_TYPE, classes = { PersonDao.class }),
// 自定义过滤规则,自定义包含规则。
@Filter(type = FilterType.CUSTOM, classes = { PersonCustomFilter.class }) }, // 禁用掉默认的过滤规则。默认的规则是扫描所有的。useDefaultFilters = false才使includeFilters只包含生效。
useDefaultFilters = false )
public class SpringApplicationConfig { @Bean(value = "person")
// @Bean给Spring容器注入一个bean对象
// bean.xml配置文件里面的class属性,在注解式开发中class类型是返回值的类型
// bean.xml配置文件里面的id属性,在注解式开发中id默认是方法名称
public Person person() {
return new Person(, "张三");
} }
自定义过滤规则,自定义包含规则。
package com.bie.filter; import java.io.IOException; import org.springframework.core.io.Resource;
import org.springframework.core.type.AnnotationMetadata;
import org.springframework.core.type.ClassMetadata;
import org.springframework.core.type.classreading.MetadataReader;
import org.springframework.core.type.classreading.MetadataReaderFactory;
import org.springframework.core.type.filter.TypeFilter; /**
*
*
* @Title: PersonCustomFilter.java
* @Package com.bie.filter
* @Description: TODO
* @author biehl
* @date 2019年12月9日
* @version V1.0
*
*/
public class PersonCustomFilter implements TypeFilter { /**
* metadataReader读取到的当前正在扫描的类的信息。
*
*
* metadataReaderFactory是一个工厂,可以获取到其他任何类的信息。
*/
@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);
// 如果包含er就会被扫描
if (className.contains("er")) {
return true;
}
return false;
} }
搞一个测试类,来进行注解版开发的使用。
package com.bie.main; import org.springframework.context.ApplicationContext;
import org.springframework.context.annotation.AnnotationConfigApplicationContext; import com.bie.config.SpringApplicationConfig;
import com.bie.po.Person; /**
*
*
* @Title: SpringApplication.java
* @Package com.bie.main
* @Description: TODO
* @author biehl
* @date 2019年12月9日
* @version V1.0
*
*/
public class SpringApplication { public static void main(String[] args) {
// 获取到注解配置类
ApplicationContext ac = new AnnotationConfigApplicationContext(SpringApplicationConfig.class);
// 根据类型获取到spring容器中的bean对象实例
Person person = ac.getBean(Person.class);
System.out.println(person.toString());
System.out.println("==========================================="); // 根据实例类型获取到spring容器中bean实例的名称
String[] beanNamesForType = ac.getBeanNamesForType(Person.class);
for (String s : beanNamesForType) {
System.out.println(s);
}
System.out.println("==========================================="); // 获取到spring容器中定义的bean实例名称。
String[] beanDefinitionNames = ac.getBeanDefinitionNames();
for (String s : beanDefinitionNames) {
System.out.println(s);
}
System.out.println("==========================================="); } }
4、组件注册@Scope设置组件作用域。@Scope指定作用范围,默认是单实例的singleton单实例,还有prototype多实例、request同一次请求创建一个实例、session同一个session创建一个实例。
package com.bie.config; import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.ComponentScan;
import org.springframework.context.annotation.ComponentScan.Filter;
import org.springframework.context.annotation.Configuration;
import org.springframework.context.annotation.FilterType;
import org.springframework.context.annotation.Scope;
import org.springframework.stereotype.Repository; import com.bie.filter.PersonCustomFilter;
import com.bie.po.Person; /**
*
*
* @Title: SpringApplicationConfig.java
* @Package com.bie.config
* @Description: TODO
* @author biehl
* @date 2019年12月9日
* @version V1.0
*
*
* 1、组件注册@Configuration、@Bean给容器中注册组件。
*
* 2、组件注册@ComponentScan自动扫描组件、指定扫描规则
*
*/
// @Configuration告诉Spring这是一个配置类,相当于bean.xml配置文件。
@Configuration
public class SpringApplicationConfig2 { @Bean(value = "person")
// @Bean给Spring容器注入一个bean对象
// bean.xml配置文件里面的class属性,在注解式开发中class类型是返回值的类型
// bean.xml配置文件里面的id属性,在注解式开发中id默认是方法名称
@Scope("prototype") // @Scope指定作用范围,默认是单实例的singleton单实例,还有prototype多实例、request同一次请求创建一个实例、session同一个session创建一个实例
// singleton单实例,ioc容器启动就会调用方法创建对象放入到ioc容器中。以后每次获取直接从容器中来拿。
// prototype多实例,ioc容器启动不会调用方法创建对象放在容器中,而是每次获取的时候才会调用方法创建对象。每次获取都会调用一遍。
public Person person() {
System.out.println("容器中添加person实例.....");
return new Person(, "张三三");
} }
测试,主类,如下所示:
package com.bie.main; import org.springframework.context.ApplicationContext;
import org.springframework.context.annotation.AnnotationConfigApplicationContext; import com.bie.config.SpringApplicationConfig2;
import com.bie.po.Person; /**
*
*
* @Title: SpringApplication.java
* @Package com.bie.main
* @Description: TODO
* @author biehl
* @date 2019年12月9日
* @version V1.0
*
*/
public class SpringApplication { public static void main(String[] args) {
// 获取到注解配置类
ApplicationContext ac = new AnnotationConfigApplicationContext(SpringApplicationConfig2.class);
System.out.println("ioc容器创建完成.....");
// 根据名称获取到spring容器中的bean对象实例
// 默认添加到spring容器中的bean实例是单实例的。
Person person = (Person) ac.getBean("person");
Person person2 = (Person) ac.getBean("person");
System.out.println("person : " + person.hashCode());
System.out.println("person2 : " + person.hashCode());
System.out.println(person == person2);
System.out.println("===========================================" + person);
System.out.println("===========================================" + person2);
} }
5、组件注册@Lazy,bean懒加载。单实例bean,默认在容器启动的时候创建对象,创建完对象将bean实例放入到容器中。懒加载就是容器启动的时候先不创建对象。当第一次使用bean实例的时候创建对象,并进行初始化。
package com.bie.config; import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.ComponentScan;
import org.springframework.context.annotation.ComponentScan.Filter;
import org.springframework.context.annotation.Configuration;
import org.springframework.context.annotation.FilterType;
import org.springframework.context.annotation.Lazy;
import org.springframework.context.annotation.Scope;
import org.springframework.stereotype.Repository; import com.bie.filter.PersonCustomFilter;
import com.bie.po.Person; /**
*
*
* @Title: SpringApplicationConfig.java
* @Package com.bie.config
* @Description: TODO
* @author biehl
* @date 2019年12月9日
* @version V1.0
*
*
* 1、组件注册@Configuration、@Bean给容器中注册组件。
*
* 2、组件注册@ComponentScan自动扫描组件、指定扫描规则
*
*/
// @Configuration告诉Spring这是一个配置类,相当于bean.xml配置文件。
@Configuration
public class SpringApplicationConfig2 { @Bean(value = "person")
// @Bean给Spring容器注入一个bean对象
// bean.xml配置文件里面的class属性,在注解式开发中class类型是返回值的类型
// bean.xml配置文件里面的id属性,在注解式开发中id默认是方法名称
@Scope("singleton") // @Scope指定作用范围,默认是单实例的singleton单实例,还有prototype多实例、request同一次请求创建一个实例、session同一个session创建一个实例
// singleton单实例,ioc容器启动就会调用方法创建对象放入到ioc容器中。以后每次获取直接从容器中来拿。
// prototype多实例,ioc容器启动不会调用方法创建对象放在容器中,而是每次获取的时候才会调用方法创建对象。每次获取都会调用一遍。
@Lazy(value = true) // 懒加载,默认是true
// 懒加载就是容器启动的时候先不创建对象。当第一次使用bean实例的时候创建对象,并进行初始化。
public Person person() {
System.out.println("容器中添加person实例.....");
return new Person(, "张三三");
} }
6、组件注册@Conditional按照条件向spring容器中注册bean实例。按照一定的条件进行判断,满足条件给容器中注册bean。如果不满足条件,则不进行bean实例的注册。
package com.bie.config; import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Conditional;
import org.springframework.context.annotation.Configuration; import com.bie.condition.LinuxCondition;
import com.bie.condition.WindowCondition;
import com.bie.po.Person; /**
*
*
* @Title: SpringApplicationConfig.java
* @Package com.bie.config
* @Description: TODO
* @author biehl
* @date 2019年12月9日
* @version V1.0
*
*
* 1、组件注册@Configuration、@Bean给容器中注册组件。
*
* 2、组件注册@ComponentScan自动扫描组件、指定扫描规则
*
*/
// @Configuration告诉Spring这是一个配置类,相当于bean.xml配置文件。
@Configuration
public class SpringApplicationConfig3 { @Bean(value = "zhangsan")
// @Bean给Spring容器注入一个bean对象
// bean.xml配置文件里面的class属性,在注解式开发中class类型是返回值的类型
// bean.xml配置文件里面的id属性,在注解式开发中id默认是方法名称
@Conditional(value = { WindowCondition.class })
// 如果是window操作系统返回zhangsan
// @Conditional注解不仅可以标注到方法上,标注到方法上表示用当前的bean按照条件进行判断。
// @Conditional注解还可以标注到类上面,标注到类上满足当前条件,这个类中配置的所有bean注册才能生效。类中组件统一设置。
public Person person() {
System.out.println("容器中添加person实例.....");
return new Person(, "张三三");
} @Bean(value = "zhaoliu")
@Conditional(value = { LinuxCondition.class })
// 如果是window操作系统返回zhaoliuliu
public Person person02() {
System.out.println("容器中添加person实例.....");
return new Person(, "赵六六");
} }
使用@Conditional注解必须实现Condition接口,然后进行条件判断的实现,如下所示:
package com.bie.condition; import org.springframework.beans.factory.config.ConfigurableListableBeanFactory;
import org.springframework.beans.factory.support.BeanDefinitionRegistry;
import org.springframework.context.annotation.Condition;
import org.springframework.context.annotation.ConditionContext;
import org.springframework.core.env.Environment;
import org.springframework.core.type.AnnotatedTypeMetadata; /**
*
*
* @Title: WindowCondition.java
* @Package com.bie.condition
* @Description: TODO
* @author biehl
* @date 2019年12月10日
* @version V1.0
*
* 判断是否是window系统。
*
*
*/
public class WindowCondition implements Condition { /**
* context判断条件能使用的上下文环境。
*
* metadata标注了Condition注解的注释信息
*/
@Override
public boolean matches(ConditionContext context, AnnotatedTypeMetadata metadata) {
// 是否是window操作系统
// 1、可以获取到ioc使用的bean工厂
ConfigurableListableBeanFactory beanFactory = context.getBeanFactory();
// 2、 获取到类加载器
ClassLoader classLoader = context.getClassLoader();
// 3、获取到环境变量信息,封装了运行时信息,环境变量,虚拟机变量等等。
Environment environment = context.getEnvironment();
// 4、获取到bean定义的注册类
BeanDefinitionRegistry registry = context.getRegistry();
// 判断容器中是否包含某一个bean实例。如果不存在还可以进行注册bean实例。
boolean containsBeanDefinition = registry.containsBeanDefinition("springApplicationConfig3"); // 判断操作系统
String osName = environment.getProperty("os.name");
if (osName.contains("Windows") && containsBeanDefinition) {
return true;
}
return false;
} }
package com.bie.condition; import org.springframework.beans.factory.config.ConfigurableListableBeanFactory;
import org.springframework.beans.factory.support.BeanDefinitionRegistry;
import org.springframework.context.annotation.Condition;
import org.springframework.context.annotation.ConditionContext;
import org.springframework.core.env.Environment;
import org.springframework.core.type.AnnotatedTypeMetadata; /**
*
*
* @Title: LinuxCondition.java
* @Package com.bie.condition
* @Description: TODO
* @author biehl
* @date 2019年12月10日
* @version V1.0
*
* 判断是否是linux系统
*/
public class LinuxCondition implements Condition { @Override
public boolean matches(ConditionContext context, AnnotatedTypeMetadata metadata) {
// 是否是window操作系统
// 1、可以获取到ioc使用的bean工厂
ConfigurableListableBeanFactory beanFactory = context.getBeanFactory();
// 2、 获取到类加载器
ClassLoader classLoader = context.getClassLoader();
// 3、获取到环境变量信息,封装了运行时信息,环境变量,虚拟机变量等等。
Environment environment = context.getEnvironment();
// 4、获取到bean定义的注册类
BeanDefinitionRegistry registry = context.getRegistry(); // 判断操作系统
String osName = environment.getProperty("os.name");
if (osName.contains("linux")) {
return true;
}
return false;
} }
测试,主类,如下所示:
package com.bie.main; import java.util.Map;
import java.util.Map.Entry;
import java.util.Set; import org.springframework.context.ApplicationContext;
import org.springframework.context.annotation.AnnotationConfigApplicationContext;
import org.springframework.core.env.Environment; import com.bie.config.SpringApplicationConfig3;
import com.bie.po.Person; /**
*
*
* @Title: SpringApplication.java
* @Package com.bie.main
* @Description: TODO
* @author biehl
* @date 2019年12月9日
* @version V1.0
*
*/
public class SpringApplication { public static void main(String[] args) {
// 获取到注解配置类
ApplicationContext ac = new AnnotationConfigApplicationContext(SpringApplicationConfig3.class);
// 获取操作系统环境变量的值
// Environment environment = ac.getEnvironment();
// String osName = environment.getProperty("os.name");
// System.out.println("==========================================" + osName); System.out.println("ioc容器创建完成.....");
// 根据名称获取到spring容器中的bean对象实例
// 默认添加到spring容器中的bean实例是单实例的。
Person zhangsan = (Person) ac.getBean("zhangsan");
// Person zhaoliu = (Person) ac.getBean("zhaoliu");
System.out.println("zhangsan : " + zhangsan.hashCode());
// System.out.println("zhaoliu : " + zhaoliu.hashCode());
System.out.println("===========================================" + zhangsan);
// System.out.println("===========================================" + zhaoliu);
System.out.println("==========================================="); // 获取到spring容器中定义的bean实例名称。
String[] beanDefinitionNames = ac.getBeanDefinitionNames();
for (String s : beanDefinitionNames) {
System.out.println(s);
}
System.out.println("==========================================="); // 根据实例类型获取到spring容器中bean实例的名称
String[] beanNamesForType = ac.getBeanNamesForType(Person.class);
for (String s : beanNamesForType) {
System.out.println(s);
}
System.out.println("==========================================="); // 根据类型获取到ioc容器中的bean实例
Map<String, Person> beansOfType = ac.getBeansOfType(Person.class);
for (Map.Entry<String, Person> entrySet : beansOfType.entrySet()) {
String key = entrySet.getKey();
Person value = entrySet.getValue();
System.out.println("key : " + key + ", " + "value : " + value);
} } }
7、组件注册@Import给容器中快速导入一个组件。重点理解哦!
给容器中注册组件。
1)、第一种方式是包扫描和组件标注注解(注解包含@Controller、@Service、@Repository、@Component等等)。具有局限性,只能将自己的类进行注解,将实例bean注入到spirng容器中。
2)、第二种方式是,@Bean注解,导入的第三方包里面的组件。
3)、第三种方式是,@Import注解,快速给容器中导入一个组件。@Import注解可以直接写要导入容器中的组件,容器中就会自动注册这个组件,id默认是全类名称。
4)、第四种方式是,组件注册使用Spring提供的FactoryBean(工厂Bean)注册组件。FactoryBean是一个接口,T getObject();调用该方法返回的的T对象放入到Bean容器中。Class<?> getObjectType();调用该方法,返回对象的类型。boolean isSingleton();调用该方法是否单例模式。
package com.bie.config; import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Conditional;
import org.springframework.context.annotation.Configuration;
import org.springframework.context.annotation.Import; import com.bie.bean.Dog;
import com.bie.condition.LinuxCondition;
import com.bie.condition.WindowCondition;
import com.bie.po.Person; /**
*
*
* @Title: SpringApplicationConfig.java
* @Package com.bie.config
* @Description: TODO
* @author biehl
* @date 2019年12月9日
* @version V1.0
*
*
* 1、组件注册@Configuration、@Bean给容器中注册组件。
*
* 2、组件注册@ComponentScan自动扫描组件、指定扫描规则
*
*/
// @Configuration告诉Spring这是一个配置类,相当于bean.xml配置文件。
@Configuration
@Import(value = { Dog.class }) // @Import注解,快速给容器中导入一个组件。
public class SpringApplicationConfig4 { }
package com.bie.bean; /**
*
*
* @Title: Dog.java
* @Package com.bie.bean
* @Description: TODO
* @author biehl
* @date 2019年12月10日
* @version V1.0
*
*/
public class Dog { }
测试,主类,如下所示:
package com.bie.main; import org.springframework.context.ApplicationContext;
import org.springframework.context.annotation.AnnotationConfigApplicationContext; import com.bie.config.SpringApplicationConfig4; /**
*
*
* @Title: SpringApplication.java
* @Package com.bie.main
* @Description: TODO
* @author biehl
* @date 2019年12月9日
* @version V1.0
*
*/
public class SpringApplication { public static void main(String[] args) {
// 获取到注解配置类
ApplicationContext ac = new AnnotationConfigApplicationContext(SpringApplicationConfig4.class);
// 获取到spring容器中定义的bean实例名称。
String[] beanDefinitionNames = ac.getBeanDefinitionNames();
for (String s : beanDefinitionNames) {
System.out.println(s);
}
System.out.println("==========================================="); } }
7.1、组件注册@Import使用ImportSelector,ImportSelector是Import的选择器。ImportSelector是一个接口,规定方法selectImports,返回值String[]字符串数组,数组里面就是类的全类名,返回需要导入的组件的全类名数组。
package com.bie.bean; import org.springframework.context.annotation.ImportSelector;
import org.springframework.core.type.AnnotationMetadata; /**
*
*
* @Title: DogImportSelector.java
* @Package com.bie.bean
* @Description: TODO
* @author biehl
* @date 2019年12月10日
* @version V1.0
*
* 自定义逻辑返回需要导入的组件
*
*/
public class DogImportSelector implements ImportSelector { /**
* 返回值就是要导入到容器中的组件全类名。
*
* importingClassMetadata,当前标注@Import注解的类的所有注解信息。
*/
@Override
public String[] selectImports(AnnotationMetadata importingClassMetadata) {
String className = importingClassMetadata.getClassName();
// @Import(value = { DogImportSelector.class })。获取到的类名是标注了该类的名称。
System.out.println("className : " + className); // 方法不能返回null,可以返回空数组
return new String[] { "com.bie.bean.Dog" };
} }
使用@Import注解可以ImportSelector这个接口。
package com.bie.config; import org.springframework.context.annotation.Configuration;
import org.springframework.context.annotation.Import; import com.bie.bean.DogImportSelector; /**
*
*
* @Title: SpringApplicationConfig.java
* @Package com.bie.config
* @Description: TODO
* @author biehl
* @date 2019年12月9日
* @version V1.0
*
*
* 1、组件注册@Configuration、@Bean给容器中注册组件。
*
* 2、组件注册@ComponentScan自动扫描组件、指定扫描规则
*
*/
// @Configuration告诉Spring这是一个配置类,相当于bean.xml配置文件。
@Configuration
@Import(value = { DogImportSelector.class }) // @Import注解,快速给容器中导入一个组件。
public class SpringApplicationConfig4 { }
7.2、组件注册@Import使用ImportBeanDefinitionRegistrar,ImportBeanDefinitionRegistrar是一个接口,规定方法registerBeanDefinitions,返回值是空void。通过调用该方法自己给容器中添加组件。importingClassMetadata是当前类的注解信息,registry是bean定义的注册类,使用registry给容器注册一个bean实例。
package com.bie.config; import org.springframework.cache.Cache;
import org.springframework.context.annotation.Configuration;
import org.springframework.context.annotation.Import; import com.bie.bean.Cat;
import com.bie.bean.Dog;
import com.bie.bean.DogImportBeanDefinitionRegistrar; /**
*
*
* @Title: SpringApplicationConfig.java
* @Package com.bie.config
* @Description: TODO
* @author biehl
* @date 2019年12月9日
* @version V1.0
*
*
* 1、组件注册@Configuration、@Bean给容器中注册组件。
*
* 2、组件注册@ComponentScan自动扫描组件、指定扫描规则
*
*/
// @Configuration告诉Spring这是一个配置类,相当于bean.xml配置文件。
@Configuration
@Import(value = { Dog.class, Cat.class, DogImportBeanDefinitionRegistrar.class }) // @Import注解,快速给容器中导入一个组件。
public class SpringApplicationConfig4 { }
ImportBeanDefinitionRegistrar是一个接口,规定方法registerBeanDefinitions,返回值是空void。通过调用该方法自己给容器中添加组件。
package com.bie.bean; import org.springframework.beans.factory.support.BeanDefinitionRegistry;
import org.springframework.beans.factory.support.RootBeanDefinition;
import org.springframework.context.annotation.ImportBeanDefinitionRegistrar;
import org.springframework.core.type.AnnotationMetadata; /**
*
*
* @Title: DogImportBeanDefinitionRegistrar.java
* @Package com.bie.bean
* @Description: TODO
* @author biehl
* @date 2019年12月10日
* @version V1.0
*
*/
public class DogImportBeanDefinitionRegistrar implements ImportBeanDefinitionRegistrar { /**
* AnnotationMetadata当前类的注解信息。
*
* BeanDefinitionRegistry是bean定义的注册类信息。把所有需要添加到容器中的bean。
* registry.registerBeanDefinition手工注册。
*/
@Override
public void registerBeanDefinitions(AnnotationMetadata importingClassMetadata, BeanDefinitionRegistry registry) {
// 判断容器中是否有dog这个bean实例对象
boolean dogDefinition = registry.containsBeanDefinition("com.bie.bean.Dog");
if (dogDefinition) {
// 指定要自定义bean名称的bean类型
RootBeanDefinition rootBeanDefinition = new RootBeanDefinition(Cat.class);
// 指定bean的名称
registry.registerBeanDefinition("cat", rootBeanDefinition);
}
} }
测试,主类,如下所示:
package com.bie.main; import org.springframework.context.ApplicationContext;
import org.springframework.context.annotation.AnnotationConfigApplicationContext; import com.bie.config.SpringApplicationConfig4; /**
*
*
* @Title: SpringApplication.java
* @Package com.bie.main
* @Description: TODO
* @author biehl
* @date 2019年12月9日
* @version V1.0
*
*/
public class SpringApplication { public static void main(String[] args) {
// 获取到注解配置类
ApplicationContext ac = new AnnotationConfigApplicationContext(SpringApplicationConfig4.class);
// 获取到spring容器中定义的bean实例名称。
String[] beanDefinitionNames = ac.getBeanDefinitionNames();
for (String s : beanDefinitionNames) {
System.out.println(s);
}
System.out.println("==========================================="); } }
7.4、第四种方式是,组件注册使用Spring提供的FactoryBean(工厂Bean)注册组件。FactoryBean是一个接口,T getObject();调用该方法返回的的T对象放入到Bean容器中。Class<?> getObjectType();调用该方法,返回对象的类型。boolean isSingleton();调用该方法是否单例模式。
默认获取到的是工厂bean调用getObject创建的对象。获取到工厂bean本身,需要给id前面加&符号。
package com.bie.bean; import org.springframework.beans.factory.FactoryBean; /**
*
*
* @Title: DogFactoryBean.java
* @Package com.bie.bean
* @Description: TODO
* @author biehl
* @date 2019年12月10日
* @version V1.0
*
* 创建spring定义的工厂bean
*/
public class DogFactoryBean implements FactoryBean<Dog> { /**
* 返回Dog对象,这个对象将会添加到容器中
*/
@Override
public Dog getObject() throws Exception {
System.out.println("getObject DogFactoryBean.......\n");
return new Dog();
} /**
* 返回对象的类型
*/
@Override
public Class<?> getObjectType() {
System.out.println("Class<?> DogFactoryBean.......\n");
return Dog.class;
} /**
* 控制是否单例模式
*/
@Override
public boolean isSingleton() {
System.out.println("isSingleton DogFactoryBean.......\n");
// 返回true代表是单实例,在容器中保存一个bean实例,返回false代表是多实例,每次获取都会创建一个新的bean实例
return true;
} }
将DogFactoryBean工厂bean注入到spring容器中。
package com.bie.config; import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration; import com.bie.bean.DogFactoryBean; /**
*
*
* @Title: SpringApplicationConfig.java
* @Package com.bie.config
* @Description: TODO
* @author biehl
* @date 2019年12月9日
* @version V1.0
*
*
* 1、组件注册@Configuration、@Bean给容器中注册组件。
*
* 2、组件注册@ComponentScan自动扫描组件、指定扫描规则
*
*/
// @Configuration告诉Spring这是一个配置类,相当于bean.xml配置文件。
@Configuration
// @Import(value = { Dog.class, Cat.class,
// DogImportBeanDefinitionRegistrar.class }) // @Import注解,快速给容器中导入一个组件。
public class SpringApplicationConfig4 { /**
* 将DogFactoryBean工厂bean注入到spring容器中
*
* @return
*/
@Bean
public DogFactoryBean dogFactoryBean() {
return new DogFactoryBean();
}
}
测试,主类,如下所示:
package com.bie.main; import org.springframework.context.ApplicationContext;
import org.springframework.context.annotation.AnnotationConfigApplicationContext; import com.bie.config.SpringApplicationConfig4; /**
*
*
* @Title: SpringApplication.java
* @Package com.bie.main
* @Description: TODO
* @author biehl
* @date 2019年12月9日
* @version V1.0
*
*/
public class SpringApplication { public static void main(String[] args) {
// 获取到注解配置类
ApplicationContext ac = new AnnotationConfigApplicationContext(SpringApplicationConfig4.class); // 工厂bean获取到的是调用getObject创建的对象。
Object bean = ac.getBean("dogFactoryBean");
System.out.println("......." + bean.getClass());
} }
8、生命周期@Bean指定初始化和销毁方法。重点理解哦!
bean的生命周期,包含创建、初始化、销毁的过程。bean的生命周期是由spring容器进行管理的。
可以自定义初始化和销毁的方法。容器在bean进行到当前生命周期的时候来调用我们自定义的初始化和销毁方法。
调用构造方法,创建对象。如果是单实例,在容器启动的时候创建对象。如果是多实例,在每次获取的时候创建对象。
单实例,调用初始化方法init-method,是在对象创建完成,并将属性值赋值完毕,开始调用初始化方法。多实例,在每次获取的时候创建对象,然后并将属性值赋值完毕,开始调用初始化方法。
单实例,调用销毁方法destory-method,在容器关闭的时候,调用销毁的方法。多实例,不调用销毁方法。spring容器不负责对多实例bean的销毁。可以手动调用销毁方法。
package com.bie.bean; /**
*
*
* @Title: Dog.java
* @Package com.bie.bean
* @Description: TODO
* @author biehl
* @date 2019年12月10日
* @version V1.0
*
*/
public class Dog { public Dog() {
// 无参构造器,创建对象的时候打印
System.out.println("dog constructor......");
} public void init() {
System.out.println("dog init 初始化方法......");
} public void destory() {
System.out.println("dog destory 销毁的方法......");
} }
8.1)、方式一、指定初始化和销毁方法。在bean.xml配置文件中可以指定init-method、destory-method配置。也可以通过@Bean注解。
package com.bie.config; import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration; import com.bie.bean.Dog; /**
*
*
* @Title: SpringApplicationConfig.java
* @Package com.bie.config
* @Description: TODO
* @author biehl
* @date 2019年12月9日
* @version V1.0
*
*
* 1、bean的生命周期,包含创建、初始化、销毁的过程。bean的生命周期是由spring容器进行管理的。
*
* 2、可以自定义初始化和销毁的方法。容器在bean进行到当前生命周期的时候来调用我们自定义的初始化和销毁方法。
*
* 3、调用构造方法,创建对象。如果是单实例,在容器启动的时候创建对象。如果是多实例,在每次获取的时候创建对象。
*
* 4、单实例,调用初始化方法init-method,是在对象创建完成,并将属性值赋值完毕,开始调用初始化方法。
* 多实例,在每次获取的时候创建对象,然后并将属性值赋值完毕,开始调用初始化方法。
*
* 5、单实例,调用销毁方法destory-method,在容器关闭的时候,调用销毁的方法。
* 多实例,不调用销毁方法。spring容器不负责对多实例bean的销毁。可以手动调用销毁方法。
*
* 6、指定初始化和销毁方法的四种方式,如下所示:
* 方式一、指定初始化和销毁方法。在bean.xml配置文件中可以指定init-method、destory-method配置。也可以通过@Bean注解。
* 方式二、生命周期InitializingBean接口和DisposableBean接口。
*
*
*
*/
// @Configuration告诉Spring这是一个配置类,相当于bean.xml配置文件。
@Configuration
public class SpringApplicationConfig5 { @Bean(value = "dog", initMethod = "init", destroyMethod = "destory")
public Dog dog() {
return new Dog();
} }
8.2)、方式二、生命周期InitializingBean接口和DisposableBean接口。通过让Bean实现InitializingBean接口定义初始化逻辑。 通过让Bean实现DisposableBean接口来进行bean实例的销毁。
InitializingBean接口里面的afterPropertiesSet方法是,创建好对象,并将属性值设置完毕以后,开始调用改方法。相当于初始化方法。
DisposableBean接口里面的destroy方法是,BeanFactory销毁的时候将单实例的bean销毁。
package com.bie.bean; import org.springframework.beans.factory.DisposableBean;
import org.springframework.beans.factory.InitializingBean;
import org.springframework.stereotype.Component; /**
*
*
* @Title: Dog.java
* @Package com.bie.bean
* @Description: TODO
* @author biehl
* @date 2019年12月10日
* @version V1.0
*
*/
@Component
public class Dog implements InitializingBean, DisposableBean { public Dog() {
// 无参构造器,创建对象的时候打印
System.out.println("dog constructor......");
} /**
* 调用初始化的方法,在bean创建完毕,属性设置完毕以后。
*/
@Override
public void afterPropertiesSet() throws Exception {
System.out.println("dog afterPropertiesSet 初始化方法......");
} /**
* 调用销毁的方法,在容器关闭的时候进行调用。
*/
@Override
public void destroy() throws Exception {
System.out.println("dog destroy 销毁的方法......");
} }
生命周期InitializingBean接口和DisposableBean接口。通过让Bean实现InitializingBean接口定义初始化逻辑。 通过让Bean实现DisposableBean接口。
package com.bie.config; import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.ComponentScan;
import org.springframework.context.annotation.Configuration; import com.bie.bean.Dog; /**
*
*
* @Title: SpringApplicationConfig.java
* @Package com.bie.config
* @Description: TODO
* @author biehl
* @date 2019年12月9日
* @version V1.0
*
*
* 1、bean的生命周期,包含创建、初始化、销毁的过程。bean的生命周期是由spring容器进行管理的。
*
* 2、可以自定义初始化和销毁的方法。容器在bean进行到当前生命周期的时候来调用我们自定义的初始化和销毁方法。
*
* 3、调用构造方法,创建对象。如果是单实例,在容器启动的时候创建对象。如果是多实例,在每次获取的时候创建对象。
*
* 4、单实例,调用初始化方法init-method,是在对象创建完成,并将属性值赋值完毕,开始调用初始化方法。
* 多实例,在每次获取的时候创建对象,然后并将属性值赋值完毕,开始调用初始化方法。
*
* 5、单实例,调用销毁方法destory-method,在容器关闭的时候,调用销毁的方法。
* 多实例,不调用销毁方法。spring容器不负责对多实例bean的销毁。可以手动调用销毁方法。
*
* 6、指定初始化和销毁方法的四种方式,如下所示:
* 方式一、指定初始化和销毁方法。在bean.xml配置文件中可以指定init-method、destory-method配置。也可以通过@Bean注解。
* 方式二、生命周期InitializingBean接口和DisposableBean接口。
* 通过让Bean实现InitializingBean接口定义初始化逻辑。 通过让Bean实现DisposableBean接口
*
*
*/
// @Configuration告诉Spring这是一个配置类,相当于bean.xml配置文件。
@Configuration
@ComponentScan(basePackages = { "com.bie.bean" })
public class SpringApplicationConfig6 { @Bean(value = "dog")
public Dog dog() {
return new Dog();
} }
测试,主类,如下所示:
package com.bie.main; import org.springframework.context.annotation.AnnotationConfigApplicationContext; import com.bie.config.SpringApplicationConfig6; /**
*
*
* @Title: SpringApplication.java
* @Package com.bie.main
* @Description: TODO
* @author biehl
* @date 2019年12月9日
* @version V1.0
*
*/
public class SpringApplication { public static void main(String[] args) {
// 获取到注解配置类
AnnotationConfigApplicationContext ac = new AnnotationConfigApplicationContext(SpringApplicationConfig6.class);
// 调用关闭的时候,调用destory销毁方法。
ac.close();
} }
8.3)、方式三、生命周期@PostConstruct&@PreDestroy。可以使用JSR250定义规范的注解。
package com.bie.bean; import javax.annotation.PostConstruct;
import javax.annotation.PreDestroy; import org.springframework.stereotype.Component; /**
*
*
* @Title: Dog.java
* @Package com.bie.bean
* @Description: TODO
* @author biehl
* @date 2019年12月10日
* @version V1.0
*
*/
@Component
public class Dog { public Dog() {
// 无参构造器,创建对象的时候打印
System.out.println("dog constructor......");
} /**
* 调用初始化的方法,在bean创建完毕,属性设置完毕以后。对象创建并赋值之后进行调用。
*/
@PostConstruct
public void init() throws Exception {
System.out.println("dog init 初始化方法......");
} /**
* 调用销毁的方法,在容器关闭的时候进行调用。容器移除对象之前调用该方法。
*/
@PreDestroy
public void destory() throws Exception {
System.out.println("dog destory 销毁的方法......");
} }
生命周期@PostConstruct(在bean实例装配完成,属性值设置完毕以后,进行初始化操作,标注在方法上)、 @PreDestroy(在容器销毁bean之前通知我们进行清理工作)。可以使用JSR250定义规范的注解。
package com.bie.config; import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.ComponentScan;
import org.springframework.context.annotation.Configuration; import com.bie.bean.Dog; /**
*
*
* @Title: SpringApplicationConfig.java
* @Package com.bie.config
* @Description: TODO
* @author biehl
* @date 2019年12月9日
* @version V1.0
*
*
* 1、bean的生命周期,包含创建、初始化、销毁的过程。bean的生命周期是由spring容器进行管理的。
*
* 2、可以自定义初始化和销毁的方法。容器在bean进行到当前生命周期的时候来调用我们自定义的初始化和销毁方法。
*
* 3、调用构造方法,创建对象。如果是单实例,在容器启动的时候创建对象。如果是多实例,在每次获取的时候创建对象。
*
* 4、单实例,调用初始化方法init-method,是在对象创建完成,并将属性值赋值完毕,开始调用初始化方法。
* 多实例,在每次获取的时候创建对象,然后并将属性值赋值完毕,开始调用初始化方法。
*
* 5、单实例,调用销毁方法destory-method,在容器关闭的时候,调用销毁的方法。
* 多实例,不调用销毁方法。spring容器不负责对多实例bean的销毁。可以手动调用销毁方法。
*
* 6、指定初始化和销毁方法的四种方式,如下所示:
* 方式一、指定初始化和销毁方法。在bean.xml配置文件中可以指定init-method、destory-method配置。也可以通过@Bean注解。
* 方式二、生命周期InitializingBean接口和DisposableBean接口。
* 通过让Bean实现InitializingBean接口定义初始化逻辑。 通过让Bean实现DisposableBean接口
* 方式三、生命周期@PostConstruct&(在bean实例装配完成,属性值设置完毕以后,进行初始化操作,标注在方法上)、 @PreDestroy(在容器销毁bean之前通知我们进行清理工作)。可以使用JSR250定义规范的注解。
*
*
*/
// @Configuration告诉Spring这是一个配置类,相当于bean.xml配置文件。
@Configuration
@ComponentScan(basePackages = { "com.bie.bean" })
public class SpringApplicationConfig7 { @Bean(value = "dog")
public Dog dog() {
return new Dog();
} }
测试,主类,如下所示:
package com.bie.main; import org.springframework.context.annotation.AnnotationConfigApplicationContext; import com.bie.config.SpringApplicationConfig7; /**
*
*
* @Title: SpringApplication.java
* @Package com.bie.main
* @Description: TODO
* @author biehl
* @date 2019年12月9日
* @version V1.0
*
*/
public class SpringApplication { public static void main(String[] args) {
// 获取到注解配置类
AnnotationConfigApplicationContext ac = new AnnotationConfigApplicationContext(SpringApplicationConfig7.class);
// 调用关闭的时候,调用destory销毁方法。
ac.close();
} }
8.4)、方式四、生命周期BeanPostProcessor后置处理器。BeanPostProcessor是一个接口,被称为bean的后置处理器。在bean初始化前后进行处理操作。
a)、postProcessBeforeInitialization方法是初始化之前进行后置处理工作,什么时候应用后置处理器,在已经创建bean实例,在bean实例任何初始化调用之前(比如InitializingBean、afterPropertiesSet、或者自定义init-method)进行工作。初始化即对象创建完成,并赋值好,调用初始化方法。BeanPostProcessor.postProcessBeforeInitialization();
b)、postProcessAfterInitialization方法是初始化之后进行后置处理工作,什么时候应用后置处理器,在bean后置处理器,这些初始化方法调用之后(比如InitializingBean、afterPropertiesSet、或者自定义init-method)进行工作。销毁即,单实例是容器关闭的时候,多实例是容器不会管理这个bean,容器不会调用销毁方法。BeanPostProcessor.postProcessAfterInitialization();
package com.bie.bean; import org.springframework.beans.BeansException;
import org.springframework.beans.factory.config.BeanPostProcessor;
import org.springframework.stereotype.Component; /**
*
*
* @Title: DogBeanPostProcessor.java
* @Package com.bie.bean
* @Description: TODO
* @author biehl
* @date 2019年12月11日
* @version V1.0
*
* 后置处理器,初始化前后进行处理工作。
*/
@Component // 添加到容器中,将后置处理器加入到容器中
public class DogBeanPostProcessor implements BeanPostProcessor { /**
*
* @param bean
* 创建的bean实例,未被初始化。
* @param beanName
* 该bean实例在容器中的名称
* @return
* @throws BeansException
*/
@Override
public Object postProcessBeforeInitialization(Object bean, String beanName) throws BeansException {
System.out.println("postProcessBeforeInitialization......" + beanName + " : " + bean);
return bean;
} /**
*
* @param bean
* 创建的bean实例,未被初始化。
* @param beanName
* 该bean实例在容器中的名称
* @return
* @throws BeansException
*/
@Override
public Object postProcessAfterInitialization(Object bean, String beanName) throws BeansException {
System.out.println("postProcessAfterInitialization......" + beanName + " : " + bean);
return bean;
} }
生命周期BeanPostProcessor后置处理器。BeanPostProcessor是一个接口,被称为bean的后置处理器。
package com.bie.config; import org.springframework.context.annotation.ComponentScan;
import org.springframework.context.annotation.Configuration; /**
*
*
* @Title: SpringApplicationConfig.java
* @Package com.bie.config
* @Description: TODO
* @author biehl
* @date 2019年12月9日
* @version V1.0
*
*
* 1、bean的生命周期,包含创建、初始化、销毁的过程。bean的生命周期是由spring容器进行管理的。
*
* 2、可以自定义初始化和销毁的方法。容器在bean进行到当前生命周期的时候来调用我们自定义的初始化和销毁方法。
*
* 3、调用构造方法,创建对象。如果是单实例,在容器启动的时候创建对象。如果是多实例,在每次获取的时候创建对象。
*
* 4、单实例,调用初始化方法init-method,是在对象创建完成,并将属性值赋值完毕,开始调用初始化方法。
* 多实例,在每次获取的时候创建对象,然后并将属性值赋值完毕,开始调用初始化方法。
*
* 5、单实例,调用销毁方法destory-method,在容器关闭的时候,调用销毁的方法。
* 多实例,不调用销毁方法。spring容器不负责对多实例bean的销毁。可以手动调用销毁方法。
*
* 6、指定初始化和销毁方法的四种方式,如下所示:
* 方式一、指定初始化和销毁方法。在bean.xml配置文件中可以指定init-method、destory-method配置。也可以通过@Bean注解。
* 方式二、生命周期InitializingBean接口和DisposableBean接口。
* 通过让Bean实现InitializingBean接口定义初始化逻辑。 通过让Bean实现DisposableBean接口
* 方式三、生命周期@PostConstruct&(在bean实例装配完成,属性值设置完毕以后,进行初始化操作,标注在方法上)、 @PreDestroy(在容器销毁bean之前通知我们进行清理工作)。可以使用JSR250定义规范的注解。
* 方式四、生命周期BeanPostProcessor后置处理器。BeanPostProcessor是一个接口,被称为bean的后置处理器。
*
*/
// @Configuration告诉Spring这是一个配置类,相当于bean.xml配置文件。
@Configuration
@ComponentScan(basePackages = { "com.bie.bean" })
public class SpringApplicationConfig8 { }
package com.bie.bean; import javax.annotation.PostConstruct;
import javax.annotation.PreDestroy; import org.springframework.stereotype.Component; /**
*
*
* @Title: Dog.java
* @Package com.bie.bean
* @Description: TODO
* @author biehl
* @date 2019年12月10日
* @version V1.0
*
*/
@Component
public class Dog { public Dog() {
// 无参构造器,创建对象的时候打印
System.out.println("dog constructor......");
} /**
* 调用初始化的方法,在bean创建完毕,属性设置完毕以后。对象创建并赋值之后进行调用。
*/
@PostConstruct
public void init() throws Exception {
System.out.println("dog init 初始化方法......");
} /**
* 调用销毁的方法,在容器关闭的时候进行调用。容器移除对象之前调用该方法。
*/
@PreDestroy
public void destory() throws Exception {
System.out.println("dog destory 销毁的方法......");
} }
测试,主类,如下所示:
package com.bie.main; import org.springframework.context.annotation.AnnotationConfigApplicationContext; import com.bie.config.SpringApplicationConfig8; /**
*
*
* @Title: SpringApplication.java
* @Package com.bie.main
* @Description: TODO
* @author biehl
* @date 2019年12月9日
* @version V1.0
*
*/
public class SpringApplication { public static void main(String[] args) {
// 获取到注解配置类
AnnotationConfigApplicationContext ac = new AnnotationConfigApplicationContext(SpringApplicationConfig8.class);
// 调用关闭的时候,调用destory销毁方法。
ac.close();
} }
总结:BeanPostProcessor.postProcessBeforeInitialization方法初始化之前可以调用。
BeanPostProcessor.postProcessAfterInitialization方法初始化之后可以调用。
初始化方法有三种通过@Bean自定义指定init-method、通过Bean实现InitializingBean接口、通过JSR250的注解@PostConstruct。
9、属性赋值@Value赋值。
package com.bie.po; import org.springframework.beans.factory.annotation.Value; import lombok.AllArgsConstructor;
import lombok.Data;
import lombok.NoArgsConstructor; /**
*
*
* @Title: Person.java
* @Package com.bie.po
* @Description: TODO
* @author biehl
* @date 2019年12月9日
* @version V1.0
*
*/
@AllArgsConstructor
@NoArgsConstructor
@Data
public class Person { // 1、使用@Value进行赋值。
// 方式一、基本数值赋值。
// 方式二、SpEL表达式。
// 方式三、使用${}获取到配置文件的值(在运行环境变量中的值) @Value("#{27-2}")
private Integer id;
@Value(value = "李四四")
private String name; }
配置文件类,如下所示:
package com.bie.bean; import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration; import com.bie.po.Person; /**
*
*
* @Title: PersonPropertyValues.java
* @Package com.bie.bean
* @Description: TODO
* @author biehl
* @date 2019年12月11日
* @version V1.0
*
*/
@Configuration
public class PersonPropertyValues { @Bean
public Person person() {
return new Person(, "张三三");
} }
测试,主类,如下所示:
package com.bie.main; import org.springframework.context.annotation.AnnotationConfigApplicationContext; import com.bie.bean.PersonPropertyValues;
import com.bie.po.Person; /**
*
*
* @Title: SpringApplication.java
* @Package com.bie.main
* @Description: TODO
* @author biehl
* @date 2019年12月9日
* @version V1.0
*
*/
public class SpringApplication { public static void main(String[] args) {
// 获取到注解配置类
AnnotationConfigApplicationContext ac = new AnnotationConfigApplicationContext(PersonPropertyValues.class);
Person person = ac.getBean(Person.class);
System.out.println(person);
// 调用关闭的时候,调用destory销毁方法。
ac.close();
} }
10、属性赋值@PropertySource加载外部配置文件。
package com.bie.bean; import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.context.annotation.PropertySource; import com.bie.po.Student; /**
*
*
* @Title: PersonPropertyValues.java
* @Package com.bie.bean
* @Description: TODO
* @author biehl
* @date 2019年12月11日
* @version V1.0
*
* 1、属性赋值@PropertySource加载外部配置文件。value可以指定文件路径或者类路径地址。
* 使用@PropertySource读取外部配置文件中的key/value对来保存运行的环境变量中。加载完外部的配置文件以后使用${}取出配置文件的值。
* 加载完外部的配置文件以后使用${}取出配置文件里面的值。
*
* 2、可以使用@PropertySources。或者多个@PropertySource注解的形式。
*/
@Configuration
@PropertySource(value = { "classpath:/spring.properties" })
public class PersonPropertyValues { @Bean
public Student student() {
return new Student();
} }
配置文件spring.properties,如下所示:
student.address=北京市西城区什刹海街道西什库大街31号院24号楼
使用${}获取到配置文件*.properties的值(在运行环境变量中的值)。
package com.bie.po; import org.springframework.beans.factory.annotation.Value; import lombok.AllArgsConstructor;
import lombok.Data;
import lombok.NoArgsConstructor; /**
*
*
* @Title: Person.java
* @Package com.bie.po
* @Description: TODO
* @author biehl
* @date 2019年12月9日
* @version V1.0
*
*/
@AllArgsConstructor
@NoArgsConstructor
@Data
public class Student { // 1、使用@Value进行赋值。
// 方式一、基本数值赋值。
// 方式二、SpEL表达式。
// 方式三、使用${}获取到配置文件*.properties的值(在运行环境变量中的值) @Value("#{27-2}")
private Integer id;
@Value(value = "李四四")
private String name; @Value("${student.address}")
private String address; }
测试,主类,如下所示:
package com.bie.main; import org.springframework.context.annotation.AnnotationConfigApplicationContext;
import org.springframework.core.env.ConfigurableEnvironment; import com.bie.bean.PersonPropertyValues;
import com.bie.po.Student; /**
*
*
* @Title: SpringApplication.java
* @Package com.bie.main
* @Description: TODO
* @author biehl
* @date 2019年12月9日
* @version V1.0
*
*/
public class SpringApplication { public static void main(String[] args) {
// 获取到注解配置类
AnnotationConfigApplicationContext ac = new AnnotationConfigApplicationContext(PersonPropertyValues.class);
Student student = ac.getBean(Student.class);
System.out.println(student); ConfigurableEnvironment environment = ac.getEnvironment();
String address = environment.getProperty("student.address");
System.out.println(address);
// 调用关闭的时候,调用destory销毁方法。
ac.close();
} }
11、自动装配@Autowired、@Qualifier、@Primary。自动装配,Spring利用依赖注入(DI)完成对IOC容器中各个组件的依赖关系赋值。
package com.bie.config; import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Qualifier;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.ComponentScan;
import org.springframework.context.annotation.Configuration;
import org.springframework.context.annotation.Primary; import com.bie.dao.PersonDao; /**
*
*
* @Title: SpringApplicationConfig.java
* @Package com.bie.config
* @Description: TODO
* @author biehl
* @date 2019年12月9日
* @version V1.0
*
*
* 1、自动装配@Autowired、@Qualifier、@Primary。
*
* 2、 自动装配,Spring利用依赖注入(DI)完成对IOC容器中各个组件的依赖关系赋值。
*
* 3、自动装配@Autowired。首先使用@Controller、@Service、@Repository注入到spring容器中。
* 然后使用@Autowired进行自动装配,实现依赖注入(DI)。完成对IOC容器中各个组件的依赖关系赋值。
* 1)、默认优先按照类型去容器中找对应的组件。找到就赋值。
* 2)、如果Ioc容器中该类型的组件有多个,如果找到多个类型相同的组件,再将属性的名称作为组件的id去容器中查找。
* 3)、@Qualifier(value = "personDao2")可以明确指定自己要装配的id,而不是使用属性名称。
* 4)、自动装配@Autowired,默认一定要将属性赋值成功。否则未找到就报异常。@Autowired(required = false)。
* 5)、@Primary让spring自动装配的时候默认使用首选的bean。此时也可以使用@Qualifier(value = "personDao")到底使用那个bean实例。
*/
// @Configuration告诉Spring这是一个配置类,相当于bean.xml配置文件。
@Configuration
@ComponentScan({ "com.bie.service", "com.bie.dao", "com.bie.controller" })
public class SpringApplicationConfig10 { /**
* 再次向spring容器中注入一个bean对象
*
* @return
*/
@Primary
@Bean(value = "personDao2")
public PersonDao personDao() {
PersonDao personDao = new PersonDao();
personDao.setLabel("");
return personDao;
} }
可以结合controller、service、dao进行测试。
package com.bie.controller; import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Controller; import com.bie.service.PersonService; /**
*
*
* @Title: PersonController.java
* @Package com.bie.controller
* @Description: TODO
* @author biehl
* @date 2019年12月9日
* @version V1.0
*
*/
@Controller
public class PersonController { @Autowired // 自动装配
private PersonService personService; }
package com.bie.service; import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Qualifier;
import org.springframework.stereotype.Service; import com.bie.dao.PersonDao; /**
*
*
* @Title: PersonService.java
* @Package com.bie.service
* @Description: TODO
* @author biehl
* @date 2019年12月9日
* @version V1.0
*
*/
@Service
public class PersonService { @Qualifier(value = "personDao")
@Autowired(required = false) // 自动装配,required = false表示如果未找到就不找了。
private PersonDao personDao2; public void show() {
System.out.println(personDao2);
} @Override
public String toString() {
return "PersonService [personDao=" + personDao2 + "]";
} }
package com.bie.dao; import org.springframework.stereotype.Repository; /**
*
*
* @Title: PersonDao.java
* @Package com.bie.dao
* @Description: TODO
* @author biehl
* @date 2019年12月9日
* @version V1.0
*
*/
@Repository
public class PersonDao { private String label = "";// 标签。判断是使用了那个名称的PersonDao public String getLabel() {
return label;
} public void setLabel(String label) {
this.label = label;
} @Override
public String toString() {
return "PersonDao [label=" + label + "]";
} }
测试,主类,如下所示:
package com.bie.main; import org.springframework.context.annotation.AnnotationConfigApplicationContext; import com.bie.config.SpringApplicationConfig10;
import com.bie.dao.PersonDao;
import com.bie.service.PersonService; /**
*
*
* @Title: SpringApplication.java
* @Package com.bie.main
* @Description: TODO
* @author biehl
* @date 2019年12月9日
* @version V1.0
*
*/
public class SpringApplication { public static void main(String[] args) {
// 获取到注解配置类
AnnotationConfigApplicationContext ac = new AnnotationConfigApplicationContext(SpringApplicationConfig10.class);
PersonService personService = ac.getBean(PersonService.class);
System.out.println(personService); // PersonDao personDao = ac.getBean(PersonDao.class);
// System.out.println(personDao); // 调用关闭的时候,调用destory销毁方法。
ac.close();
} }
12、 自动装配@Resource、@Inject。
package com.bie.config; import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.ComponentScan;
import org.springframework.context.annotation.Configuration;
import org.springframework.context.annotation.Primary; import com.bie.dao.PersonDao; /**
*
*
* @Title: SpringApplicationConfig.java
* @Package com.bie.config
* @Description: TODO
* @author biehl
* @date 2019年12月9日
* @version V1.0
*
*
* 1、Spring还支持使用@Resource(JSR250规范)、@Inject(JSR330规范)。是java规范的注解。
* 2、@Resource是java规范,和@Autowired一样实现了自动装配功能,但是默认是按照组件名称进行装配的。
* 不支持@Primary,也不支持@Autowired(required = false)。
* 3、@Inject,需要导入javax.inject的jar包。和@Autowired功能一样。没有required=false。
*
*/
// @Configuration告诉Spring这是一个配置类,相当于bean.xml配置文件。
@Configuration
@ComponentScan({ "com.bie.service", "com.bie.dao", "com.bie.controller" })
public class SpringApplicationConfig11 { /**
* 再次向spring容器中注入一个bean对象
*
* @return
*/
@Primary
@Bean(value = "personDao2")
public PersonDao personDao() {
PersonDao personDao = new PersonDao();
personDao.setLabel("");
return personDao;
} }
将@Resource、@Inject替换@Autowired进行测试。
package com.bie.service; import javax.annotation.Resource;
import javax.inject.Inject; import org.springframework.stereotype.Service; import com.bie.dao.PersonDao; /**
*
*
* @Title: PersonService.java
* @Package com.bie.service
* @Description: TODO
* @author biehl
* @date 2019年12月9日
* @version V1.0
*
*/
@Service
public class PersonService { // @Qualifier(value = "personDao")
// @Autowired(required = false) // 自动装配,required = false表示如果未找到就不找了。
//@Resource(name = "personDao2") // 按照名称进行装配.
@Inject //
private PersonDao personDao2; public void show() {
System.out.println(personDao2);
} @Override
public String toString() {
return "PersonService [personDao=" + personDao2 + "]";
} }
13、自动装配方法、构造器位置的自动装配。@Autowired可以标注到构造器、方法、参数、属性字段。都是从容器中获取到参数组件的值。
package com.bie.bean; import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Component; /**
*
*
* @Title: Boos.java
* @Package com.bie.bean
* @Description: TODO
* @author biehl
* @date 2019年12月12日
* @version V1.0
*
* 默认加在ioc容器中的组件,容器启动会调用无参构造器创建对象,再进行初始化赋值操作。
*/
@Component
public class Boos { // 第一种方法,标注到对象上
// @Autowired
private Car car; public Car getCar() {
return car;
} // 第二种方法,标注到方法上。spring容器创建当前对象就会调用方法完成赋值。
// 方法使用的参数,自定义类型的值从IOC容器中获取。
// @Autowired
public void setCar(Car car) {
this.car = car;
} // 第三种方法,标注到构造器上面。spring启动的时候调用该含参构造器。
// 构造器要用的组件,也都是从spring容器中获取到的。
// @Autowired
// public Boos(Car car) {
// this.car = car;
// System.out.println("Boss的含参构造器......");
// } // 第四种方法,标注到参数上面,和第三种方法一样。如果组件只有一个有参构造器,这个有参构造器可以省略@Autowired注解的。
// 参数位置的组件还是可以自动从容器中获取的。
// public Boos(@Autowired Car car) {
// this.car = car;
// System.out.println("Boss的含参构造器......");
// } @Override
public String toString() {
return "Boos [car=" + car + "]";
} }
@Configuration告诉Spring这是一个配置类,相当于bean.xml配置文件。
package com.bie.config; import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.ComponentScan;
import org.springframework.context.annotation.Configuration; import com.bie.bean.Boos;
import com.bie.bean.Car; /**
*
*
* @Title: SpringApplicationConfig.java
* @Package com.bie.config
* @Description: TODO
* @author biehl
* @date 2019年12月9日
* @version V1.0
*
*
* 1、@Autowired可以标注到构造器、方法、参数、属性字段。都是从容器中获取到参数组件的值。
* 第一种方法, @Autowired可以标注到构造器。
* 第二种方法,@Autowired可以标注到方法。标注到方法上。spring容器创建当前对象就会调用方法完成赋值。
* 第三种方法, @Autowired可以标注到参数。标注到构造器上面。spring启动的时候调用该含参构造器。
* 第四种方法,@Autowired可以标注到属性字段。标注到参数上面,和第三种方法一样。如果组件只有一个有参构造器,这个有参构造器可以省略@Autowired注解的。
* 第五种方法,@Autowired可以标注到@Bean注解的参数上面,也可以省略@Autowired。
* @Bean加方法参数,参数从spring容器中获取到。默认是不写@Autowired,效果是一样的。都可以自动装配。
*
*/
// @Configuration告诉Spring这是一个配置类,相当于bean.xml配置文件。
@Configuration
@ComponentScan({ "com.bie.bean" })
public class SpringApplicationConfig12 { //第五种方法,@Autowired可以标注到@Bean注解的参数上面,也可以省略@Autowired。
@Bean
public Boos boos(@Autowired Car car) {
Boos boos = new Boos();
boos.setCar(car);
return boos;
}
}
测试,主类,如下所示:
package com.bie.main; import org.springframework.context.annotation.AnnotationConfigApplicationContext; import com.bie.bean.Boos;
import com.bie.bean.Car;
import com.bie.config.SpringApplicationConfig12;
import com.bie.service.PersonService; /**
*
*
* @Title: SpringApplication.java
* @Package com.bie.main
* @Description: TODO
* @author biehl
* @date 2019年12月9日
* @version V1.0
*
*/
public class SpringApplication { public static void main(String[] args) {
// 获取到注解配置类
AnnotationConfigApplicationContext ac = new AnnotationConfigApplicationContext(SpringApplicationConfig12.class);
Boos boos = ac.getBean(Boos.class);
Car car = ac.getBean(Car.class);
System.out.println(boos);
System.out.println(car);
// 调用关闭的时候,调用destory销毁方法。
ac.close();
} }
14、自动装配Aware注入Spring底层组件。自定义组件想要使用spring容器底层的一些组件,比如applicationContext、BeanFactory等等。只需要自定义组件实现xxxAware接口即可。在创建对象的时候,会调用接口规定的方法注入相关的组件。可以把Spring底层中的一些组件注入到自定义的bean容器中。 xxxAware的功能是使用xxxAwareProcessor进行处理的,每个xxxAware都有对应的xxxAwareProcessor。
package com.bie.bean; import org.springframework.beans.BeansException;
import org.springframework.beans.factory.BeanNameAware;
import org.springframework.context.ApplicationContext;
import org.springframework.context.ApplicationContextAware;
import org.springframework.context.EmbeddedValueResolverAware;
import org.springframework.stereotype.Component;
import org.springframework.util.StringValueResolver; /**
*
*
* @Title: Red.java
* @Package com.bie.bean
* @Description: TODO
* @author biehl
* @date 2019年12月12日
* @version V1.0
*
* ApplicationContextAware接口继承了Aware接口。
*/
@Component // 将Red对象添加到ioc容器中
public class Red implements ApplicationContextAware, BeanNameAware, EmbeddedValueResolverAware { // ApplicationContext代表了IOC容器
private ApplicationContext applicationContext; /**
* ApplicationContext代表的是ioc容器
*/
@Override
public void setApplicationContext(ApplicationContext applicationContext) throws BeansException {
System.out.println("传入的ioc: " + applicationContext);
this.applicationContext = applicationContext;
} /**
* 设置IOC容器中bean实例的名称
*/
@Override
public void setBeanName(String name) {
System.out.println("当前bean的名称: " + name);
} /**
* StringValueResolver是解析String字符串的占位符
*/
@Override
public void setEmbeddedValueResolver(StringValueResolver resolver) {
String resolveStringValue = resolver.resolveStringValue("您好,${os.name},我是#{1008611}");
System.out.println("解析的字符串是 : " + resolveStringValue);
} }
@Configuration告诉Spring这是一个配置类,相当于bean.xml配置文件。
package com.bie.config; import org.springframework.context.annotation.ComponentScan;
import org.springframework.context.annotation.Configuration; /**
*
*
* @Title: SpringApplicationConfig.java
* @Package com.bie.config
* @Description: TODO
* @author biehl
* @date 2019年12月9日
* @version V1.0
*
*
* 1、自定义组件想要使用spring容器底层的一些组件,比如applicationContext、BeanFactory等等。
* 只需要自定义组件实现xxxAware接口即可。在创建对象的时候,会调用接口规定的方法注入相关的组件。
* 可以把Spring底层中的一些组件注入到自定义的bean容器中。
* 2、xxxAware的功能是使用xxxAwareProcessor进行处理的,每个xxxAware都有对应的xxxAwareProcessor。
*
*/
// @Configuration告诉Spring这是一个配置类,相当于bean.xml配置文件。
@Configuration
@ComponentScan({ "com.bie.bean" })
public class SpringApplicationConfig13 { }
测试,主类,如下所示:
package com.bie.main; import org.springframework.context.annotation.AnnotationConfigApplicationContext; import com.bie.config.SpringApplicationConfig13; /**
*
*
* @Title: SpringApplication.java
* @Package com.bie.main
* @Description: TODO
* @author biehl
* @date 2019年12月9日
* @version V1.0
*
*/
public class SpringApplication { public static void main(String[] args) {
// 获取到注解配置类
AnnotationConfigApplicationContext ac = new AnnotationConfigApplicationContext(SpringApplicationConfig13.class); // 调用关闭的时候,调用destory销毁方法。
ac.close();
} }
15、自动装配@Profile环境搭建,自动装配@Profile根据环境注册bean。
package com.bie.config; import java.beans.PropertyVetoException; import javax.sql.DataSource; import org.springframework.beans.factory.annotation.Value;
import org.springframework.context.EmbeddedValueResolverAware;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.context.annotation.Profile;
import org.springframework.context.annotation.PropertySource;
import org.springframework.util.StringValueResolver; import com.mchange.v2.c3p0.ComboPooledDataSource; /**
*
*
* @Title: SpringApplicationConfig.java
* @Package com.bie.config
* @Description: TODO
* @author biehl
* @date 2019年12月9日
* @version V1.0
*
*
* 1、@Profile注解。spring提供了可以根据当前环境动态的激活和切换一系列bean组件的功能。
*
* 2、@Profile做标识,当前环境被激活了才会被注册到spring容器中。
* 指定组件在那个环境的情况下才会被注册到容器中。不指定,任何环境下都能注册这个组件。
*
* 3、添加了环境标识的bean,只有这个环境被激活以后的时候才能注册到容器中。可以使用default默认的。默认是default环境。
*
* 4、切换环境的几种方式。
* 方式一、-Dspring.profiles.active=test。使用命令行动态参数,在虚拟机参数位置加载。
* 方式二、使用代码的方式激活是那种环境。啊,真没有springboot好使方便哦。
* 方式三、@Profile(value = "dev")标注到类上,只有是指定的环境的时候,整个配置类里面的所有配置才能生效。
* 注意:注入到容器中的bean,没有标注环境标识的bean,在任何环境下都是加载的。
*/
// @Configuration告诉Spring这是一个配置类,相当于bean.xml配置文件。
@Profile(value = "test")
@Configuration
@PropertySource(value = {"classpath:/jdbc.properties"})
public class SpringApplicationConfig14 implements EmbeddedValueResolverAware { // 值解析器
private StringValueResolver valueResolver; private String jdbcUrl;
private String driverClass; // 使用值解析器进行解析
@Value(value = "${jdbc.username}")
private String user; /**
* 开发环境
*
* @return
*/
@Bean(value = "DataSourceDev")
@Profile(value = "dev")
public DataSource dataSourceDev(@Value(value = "jdbc.password") String password) {
ComboPooledDataSource dataSource = new ComboPooledDataSource();
try {
dataSource.setJdbcUrl("jdbc:mysql://localhost:3306/dev");
dataSource.setDriverClass(driverClass);
dataSource.setUser(user);
dataSource.setPassword(password);
} catch (PropertyVetoException e) {
e.printStackTrace();
}
return dataSource;
} /**
* 生产环境
*
* @return
*/
@Bean(value = "DataSourceProd")
@Profile(value = "prod")
public DataSource dataSourceProd(@Value(value = "jdbc.password") String password) {
ComboPooledDataSource dataSource = new ComboPooledDataSource();
try {
dataSource.setJdbcUrl("jdbc:mysql://localhost:3306/prod");
dataSource.setDriverClass(driverClass);
dataSource.setUser(user);
dataSource.setPassword(password);
} catch (PropertyVetoException e) {
e.printStackTrace();
}
return dataSource;
} /**
* 测试环境
*
* @return
*/
@Bean(value = "DataSourceTest")
@Profile(value = "test")
// @Profile(value = "default")
public DataSource dataSourceTest(@Value(value = "jdbc.password") String password) {
ComboPooledDataSource dataSource = new ComboPooledDataSource();
try {
dataSource.setJdbcUrl("jdbc:mysql://localhost:3306/test");
dataSource.setDriverClass(driverClass);
dataSource.setUser(user);
dataSource.setPassword(password);
} catch (PropertyVetoException e) {
e.printStackTrace();
}
return dataSource;
} /**
* 值解析器
*/
@Override
public void setEmbeddedValueResolver(StringValueResolver resolver) {
this.valueResolver = resolver;
driverClass = resolver.resolveStringValue("${jdbc.driver}");
}
}
测试,主类,如下所示:
package com.bie.main; import org.springframework.context.annotation.AnnotationConfigApplicationContext; import com.bie.config.SpringApplicationConfig14; /**
*
*
* @Title: SpringApplication.java
* @Package com.bie.main
* @Description: TODO
* @author biehl
* @date 2019年12月9日
* @version V1.0
*
*/
public class SpringApplication { public static void main(String[] args) {
// 获取到注解配置类
AnnotationConfigApplicationContext ac = new AnnotationConfigApplicationContext();
// 1、第一步,创建好ApplicationContext对象。
// 2、第二步,设置需要激活的对象。
ac.getEnvironment().setActiveProfiles("test");
// 3、第三步,注册配置类
ac.register(SpringApplicationConfig14.class);
// 4、第四步,启动刷新容器。
ac.refresh(); String[] beanDefinitionNames = ac.getBeanDefinitionNames();
for (String s : beanDefinitionNames) {
System.out.println(s);
}
// 调用关闭的时候,调用destory销毁方法。
ac.close();
} }
aaarticlea/jpeg;base64,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" alt="" />
作者:别先生
博客园:https://www.cnblogs.com/biehongli/
如果您想及时得到个人撰写文章以及著作的消息推送,可以扫描上方二维码,关注个人公众号哦。
Spring常用注解式开发的更多相关文章
- Spring MVC注解式开发
MVC注解式开发即处理器基于注解的类开发, 对于每一个定义的处理器, 无需在xml中注册. 只需在代码中通过对类与方法的注解, 即可完成注册. 定义处理器 @Controller: 当前类为处理器 @ ...
- Spring MVC (二)注解式开发使用详解
MVC注解式开发即处理器基于注解的类开发, 对于每一个定义的处理器, 无需在xml中注册. 只需在代码中通过对类与方法的注解, 即可完成注册. 定义处理器 @Controller: 当前类为处理器 @ ...
- 3.2.3 SpringMVC注解式开发
SpringMVC注解式开发 1. 搭建环境 (1) 后端控制器无需实现接口 , 添加相应注解 Controller类添加注解 @Controller //该注解表将当前类交给spring容器管理 @ ...
- shiro授权、注解式开发
在ShiroUserMapper.xml中新增内容 <select id="getRolesByUserId" resultType="java.lang.Stri ...
- Shiro授权及注解式开发
目的: shiro授权 shiro注解式开发 Shiro授权 首先设计shiro权限表: 从图中我们也清晰的看出五张表之间的关系 ShiroUserMapper Set<String> g ...
- Spring系列之Spring常用注解总结
传统的Spring做法是使用.xml文件来对bean进行注入或者是配置aop.事物,这么做有两个缺点:1.如果所有的内容都配置在.xml文件中,那么.xml文件将会十分庞大:如果按需求分开.xml文件 ...
- 总结切面编程AOP的注解式开发和XML式开发
有段日子没有总结东西了,因为最近确实有点忙,一直在忙于hadoop集群的搭建,磕磕碰碰现在勉强算是能呼吸了,因为这都是在自己的PC上,资源确实有点紧张(搭建过程后期奉上),今天难得大家都有空(哈哈哈~ ...
- Spring常用注解介绍【经典总结】
Spring的一个核心功能是IOC,就是将Bean初始化加载到容器中,Bean是如何加载到容器的,可以使用Spring注解方式或者Spring XML配置方式. Spring注解方式减少了配置文件内容 ...
- spring中注解式事务不生效的问题
常用的解决方法可以百度,我针对我的问题描述一下 Mysql中InnoDB引擎才支持事务, MyISAM不支持事务. 当你尝试了各种方法解决spring中注解式事务不生效时, 一定要查看一下数据库中表的 ...
随机推荐
- 基于TCP协议之socket编程
#服务端 #导入一个socket模块 import socket #想象成买手机打电话:socket.SOCK_STREAM 表示建立tcp连接 ,udp连接socket.SOCK_DGRAM #买了 ...
- Linux Bash文本操作之grep篇
Linux grep命令用于查找文件里符合条件的字符串.是文本检索中常用的工具之一. grep 指令在文件中查找能够匹配指定模式字符串的行.如果没有指定文件名,或者文件名为 - ,则从标准输入设 ...
- Kotlin 编程语言成为其 Android 应用程序开发人员的首选语言
今年 5 月,谷歌在 I/O 大会上宣布,Kotlin 编程语言成为其 Android 应用程序开发人员的首选语言. Kotlin 是一种面向现代多平台应用程序的编程语言,成为谷歌开发 Android ...
- 阿里云esc 安装 mysql8.0
打开 连接工具,我用的是 MobaXterm_Personal_12.1 (官网下载地址:https://moba.en.softonic.com/) 连接到 ecs,然后移除 默认的 mariadb ...
- ZKWeb网页框架2.2.1正式发布
2.2.1 更新的内容有 改进 EFCore 支持 支持自动 json 序列化字段 (通过 WithSerialization 选项) 支持懒加载 更新后 EFCore 可以使用所有默认插件 (ZKW ...
- 网络爬虫引发的问题及robots协议
一.网络爬虫的尺寸 1.以爬取网页,玩转网页为目的进行小规模,数据量小对爬取速度不敏感的可以使用request库实现功能(占90%) 2.以爬取网站或爬取系列网站为目的,比如说获取一个或多个旅游网站的 ...
- Java之数据库表字段有关键字报错java.sql.SQLSyntaxErrorException
前两天在开发中遇到一个坑,本来我在快乐的做着增删改查,然后悲剧发生了,在查询数据库的过程中,报了java.sql.SQLSyntaxErrorException: 经过排查,是因为数据库表字段中存在关 ...
- IT兄弟连 HTML5教程 CSS3属性特效 文字描边
用CSS3实现的文字描边效果,一个CSS3文字特效实例,字体可以自己随意改,字体颜色也可以自己改.IE9以下浏览器无效果,所以提醒大家测试时候要使用Google Chrome.-webkit-text ...
- 最近上传图片上传文件报413错误及仅Https下报413问题,IIS高版本的配置方案及Web.config配置全解
IIS文件上传大小限制30M,C盘中有的IIS_schema.xml文件 C:\Windows\System32\inetsrv\config\schema\ 但是考虑到安全等问题,而且这个文件默认是 ...
- go路由httprouter中的压缩字典树算法图解及c++实现
目录 go路由httprouter中的压缩字典树算法图解及c++实现 前言 httprouter简介 压缩字典树 概念 插入操作 查询操作 c+++实现 go路由httprouter中的压缩字典树算法 ...