Spring注解开发
Spring注解开发
常见注解
@ComponentScan
excludeFilters 排除过滤选择器
includeFilters 包含过滤选择器(使用该选择器需要设置useDefaultFilters = false)
FilterType.ANNOTATION 按照注解
FilterType.ASSIGNABLE_TYPE 按照给定的类型
FilterType.ASPECTJ 使用AspectJ表达式
FilterType.REGEX 使用正则表达式
FilterType.CUSTOM 使用自定义规则
示例:FilterType.CUSTOM
package org.example.filter;
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;
import java.io.IOException;
/**
* 自定义组件扫描规则
* @author admin
*/
public class MyTypeFilter implements TypeFilter {
@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();
//全类名中包含service的类注入ioc容器中
if(className.contains("service")){
//返回true注入ioc容器
return true;
}
//返回false不注入ioc容器
return false;
}
}
@ComponentScan(value = "org.example", useDefaultFilters = false, includeFilters = {
@ComponentScan.Filter(type = FilterType.CUSTOM, classes = {MyTypeFilter.class})
})
@Configuration
作用:告诉spring这是一个配置类,并将该类注入ioc容器
/**
* @Configuration 表示该类是一个配置类
*/
@Configuration
public class SpringConfig {
}
@Scope
作用:设置Bean的作用域
@Scope 设置Bean的作用域
prototype 多例(获取对象时创建对象)
singleton 单例(默认,ioc容器初始化时创建对象)
request 同一次请求创建一个实例
session 同一次会话创建一个实例
@Scope("prototype")
public Person person(){
return new Person("李四",22);
}
@Lazy
作用:懒加载
单例bean默认在容器初始化时创建对象;
懒加载后,容器初始化时不创建对象,第一次获取bean对象时创建对象并初始化。
@Conditional
作用:按照条件将bean注入到ioc容器中
package org.example.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;
/**
* 系统环境为Linux时将bean注入到ioc容器中
* @author admin
*/
public class LinuxCondition implements Condition {
/**
*
* @param conditionContext 判断条件能使用的上下文
* @param annotatedTypeMetadata 注释信息
* @return
*/
@Override
public boolean matches(ConditionContext conditionContext, AnnotatedTypeMetadata annotatedTypeMetadata) {
//获取ioc容器使用beanFactory(bean工厂)
ConfigurableListableBeanFactory beanFactory = conditionContext.getBeanFactory();
//获取类加载器
ClassLoader classLoader = conditionContext.getClassLoader();
//获取当前环境信息
Environment environment = conditionContext.getEnvironment();
//获取bean定义的注册类
BeanDefinitionRegistry registry = conditionContext.getRegistry();
System.out.println(beanFactory);
System.out.println(classLoader);
System.out.println(environment);
System.out.println(registry);
String osName = environment.getProperty("os.name");
if(osName.contains("Linux")){
return true;
}
return false;
}
}
package org.example.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;
/**
* 系统环境为Window时将bean注入到ioc容器中
* @author admin
*/
public class WindowCondition implements Condition {
/**
*
* @param conditionContext 判断条件能使用的上下文
* @param annotatedTypeMetadata 注释信息
* @return
*/
@Override
public boolean matches(ConditionContext conditionContext, AnnotatedTypeMetadata annotatedTypeMetadata) {
//获取ioc容器使用beanFactory(bean工厂)
ConfigurableListableBeanFactory beanFactory = conditionContext.getBeanFactory();
//获取类加载器
ClassLoader classLoader = conditionContext.getClassLoader();
//获取当前环境信息
Environment environment = conditionContext.getEnvironment();
//获取bean定义的注册类
BeanDefinitionRegistry registry = conditionContext.getRegistry();
System.out.println(beanFactory);
System.out.println(classLoader);
System.out.println(environment);
System.out.println(registry);
String osName = environment.getProperty("os.name");
if(osName.contains("Window")){
return true;
}
return false;
}
}
@Bean
@Conditional({WindowCondition.class})
public Person person(){
return new Person("李四",22);
}
@Bean
@Conditional({LinuxCondition.class})
public Student student(){
return new Student("1001","张三");
}
@Import
作用:将组件注入到ioc容器中,id默认为全类名
ImportSelector
package org.example.filter;
import org.springframework.context.annotation.ImportSelector;
import org.springframework.core.type.AnnotationMetadata;
import java.util.Set;
/**
* 自定义需要注入ioc容器的组件
* @author admin
*/
public class MyImportSelector implements ImportSelector {
/**
* 返回值就是导入ioc容器中组件的全类名
* @param annotationMetadata
* @return
*/
@Override
public String[] selectImports(AnnotationMetadata annotationMetadata) {
return new String[]{"org.example.pojo.Color"};
}
}
ImportBeanDefinitionRegistrar
package org.example.filter;
import org.example.pojo.Color;
import org.springframework.beans.factory.support.BeanDefinitionRegistry;
import org.springframework.beans.factory.support.BeanNameGenerator;
import org.springframework.beans.factory.support.RootBeanDefinition;
import org.springframework.context.annotation.ImportBeanDefinitionRegistrar;
import org.springframework.core.type.AnnotationMetadata;
/**
* @author admin
*/
public class MyImportBeanDefinitionRegistrar implements ImportBeanDefinitionRegistrar {
/**
*
* @param importingClassMetadata 当前类的注解信息
* @param registry beanDefinition注册类
*/
@Override
public void registerBeanDefinitions(AnnotationMetadata importingClassMetadata, BeanDefinitionRegistry registry) {
registry.registerBeanDefinition("color", new RootBeanDefinition(Color.class));
String[] beanDefinitionNames = registry.getBeanDefinitionNames();
for (String beanDefinitionName : beanDefinitionNames) {
System.out.println(beanDefinitionName);
}
}
}
示例:
@Configuration
@Import({Color.class, MyImportSelector.class, MyImportBeanDefinitionRegistrar.})
public class SpringConfig {
}
@PropertySource
作用:加载配置文件
package org.example;
import org.example.pojo.Person;
import org.springframework.context.annotation.*;
/**
* @PropertySource 将person.properties配置文件加载到运行环境中
*/
@Configuration
@PropertySource({"classpath:person.properties"})
public class SpringConfig {
@Bean
public Person person(){
return new Person();
}
}
@Value
作用:给对象中的属性赋值
package org.example.pojo;
import lombok.AllArgsConstructor;
import lombok.Data;
import lombok.NoArgsConstructor;
import org.springframework.beans.factory.annotation.Value;
/**
* @author admin
*/
@Data
@AllArgsConstructor
@NoArgsConstructor
public class Person {
/**
* 使用@Value赋值
* 1、基本类型的值
* 2、可以写SpEL;#{}
* 3、可以写${};取出配置文件中的值(在运行环境)
*/
@Value("未知")
private String name;
@Value("#{5-5}")
private int age;
@Value("${nickname}")
private String nickname;
}
@Autowired
作用:默认按照类型自动注入
package org.example.controller;
import lombok.Data;
import org.example.service.UserService;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Controller;
/**
* @author admin
*/
@Controller
@Data
public class UserController {
/**
* @Autowired 默认按照类型去容器中找对应的组件,如果找到多个相同类型的组件,再将属性的名称作为组件的id去容器中查找
*/
@Autowired
private UserService userService;
public void show(){
System.out.println("userController-show");
}
}
@Qualifier
作用:配合@Autowired使用,按照组件id装配
package org.example.controller;
import lombok.Data;
import org.example.service.UserService;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Qualifier;
import org.springframework.stereotype.Controller;
/**
* @author admin
*/
@Controller
@Data
public class UserController {
/**
* @Qualifier 如果找到多个相同类型的组件,根据组件id自动装配
*/
@Autowired
@Qualifier("userService")
private UserService userService;
public void show(){
System.out.println("userController-show");
}
}
@Primary
作用:spring自动装配的时候,默认使用首选的bean,也可以继续使用@Qualifier指定需要装配的bean的名字
@Resource(JSR50)
作用:和@Autowired一样实现自动装配功能;默认按照组件名称进行装配
注意:不支持@Primary注解
@Inject(JSR330)
作用:和@Autowired功能一样
注意:需要导入javax.inject包
@Profile
作用:指定组件在哪个环境的情况下才能被注册到容器中,如果不指定则任何环境下都能注册这个组件
@Configuration
@ComponentScan("org.example")
public class SpringConfig {
@Bean
@Profile("pro")
public DataSource dataSourcePro(){
ComboPooledDataSource dataSource = new ComboPooledDataSource();
dataSource.setMaxPoolSize(100);
return dataSource;
}
@Bean
@Profile("dev")
public DataSource dataSourceDev(){
ComboPooledDataSource dataSource = new ComboPooledDataSource();
dataSource.setMaxPoolSize(10);
return dataSource;
}
}
@Test
public void testProfile(){
//用代码的方式激活环境
AnnotationConfigApplicationContext context = new AnnotationConfigApplicationContext();
context.getEnvironment().setActiveProfiles("pro");
context.register(SpringConfig.class);
context.refresh();
ComboPooledDataSource dataSource = (ComboPooledDataSource) context.getBean(DataSource.class);
System.out.println(dataSource.getMaxPoolSize());
}
Aop
package org.example.aop;
import org.aspectj.lang.annotation.Aspect;
import org.springframework.stereotype.Component;
@Component
public class MathUtil {
public int div(int i, int j){
return i/j;
}
}
package org.example.aop;
import org.aspectj.lang.JoinPoint;
import org.aspectj.lang.annotation.*;
import org.springframework.stereotype.Component;
import java.util.Arrays;
@Component
@Aspect
public class LogAspect {
@Pointcut("execution(* org.example.aop.MathUtil.*(..))")
public void pointCut(){}
@Before("pointCut()")
public void logStart(JoinPoint joinPoint){
Object[] args = joinPoint.getArgs();
System.out.println(joinPoint.getSignature().getName()+"开始执行。。。参数列表是:"+ Arrays.asList(args));
}
@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 = "exception")
public void logException(JoinPoint joinPoint, Exception exception){
System.out.println(joinPoint.getSignature().getName() + "执行异常。。。异常信息:{"+ exception +"}");
}
}
package org.example;
import com.mchange.v2.c3p0.ComboPooledDataSource;
import org.example.condition.LinuxCondition;
import org.example.condition.WindowCondition;
import org.example.factory.ColorFactoryBean;
import org.example.filter.MyImportBeanDefinitionRegistrar;
import org.example.filter.MyImportSelector;
import org.example.filter.MyTypeFilter;
import org.example.pojo.Color;
import org.example.pojo.Person;
import org.example.pojo.Student;
import org.springframework.context.annotation.*;
import org.springframework.stereotype.Controller;
import org.springframework.stereotype.Service;
import javax.sql.DataSource;
/**
* @EnableAspectJAutoProxy 开启spring aop自动代理
*/
@Configuration
@ComponentScan("org.example")
@EnableAspectJAutoProxy
public class SpringConfig {
}
@Test
public void testAop(){
AnnotationConfigApplicationContext context = new AnnotationConfigApplicationContext(SpringConfig.class);
MathUtil math = context.getBean(MathUtil.class);
int result = math.div(2, 0);
System.out.println("结果为:"+result);
}
声明式事务
package org.example.dao;
import org.example.pojo.Account;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.jdbc.core.BeanPropertyRowMapper;
import org.springframework.jdbc.core.JdbcTemplate;
import org.springframework.stereotype.Repository;
import java.util.List;
/**
* @author admin
*/
@Repository
public class AccountDao {
@Autowired
private JdbcTemplate jdbcTemplate;
public Account queryAccountById(int id){
Account account = jdbcTemplate.queryForObject("select * from account where id=?", new BeanPropertyRowMapper<>(Account.class), id);
return account;
}
public List<Account> queryAllAccount(){
List<Account> accounts = jdbcTemplate.query("select * from account", new BeanPropertyRowMapper<Account>(Account.class));
return accounts;
}
public int updateAccount(Account account){
int row = jdbcTemplate.update("update account set name=?,money=? where id=?", account.getName(), account.getMoney(), account.getId());
return row;
}
}
package org.example.service;
import org.example.dao.AccountDao;
import org.example.pojo.Account;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
import java.util.List;
/**
* @author admin
*/
@Service
public class AccountService {
@Autowired
private AccountDao accountDao;
public List<Account> queryAllAccount(){
List<Account> accounts = accountDao.queryAllAccount();
return accounts;
}
public Account queryAccountById(int id){
Account account = accountDao.queryAccountById(id);
return account;
}
@Transactional
public boolean updateAccount(Account account){
int row = accountDao.updateAccount(account);
if(row>0){
return true;
}
return false;
}
}
package org.example;
import com.mchange.v2.c3p0.ComboPooledDataSource;
import org.example.condition.LinuxCondition;
import org.example.condition.WindowCondition;
import org.example.factory.ColorFactoryBean;
import org.example.filter.MyImportBeanDefinitionRegistrar;
import org.example.filter.MyImportSelector;
import org.example.filter.MyTypeFilter;
import org.example.pojo.Color;
import org.example.pojo.Person;
import org.example.pojo.Student;
import org.springframework.context.annotation.*;
import org.springframework.jdbc.core.*;
import org.springframework.jdbc.datasource.DataSourceTransactionManager;
import org.springframework.stereotype.Controller;
import org.springframework.stereotype.Service;
import org.springframework.transaction.TransactionManager;
import org.springframework.transaction.annotation.EnableTransactionManagement;
import javax.sql.DataSource;
import java.beans.PropertyVetoException;
@Configuration
@ComponentScan("org.example")
@EnableTransactionManagement
public class SpringConfig {
@Bean
public TransactionManager transactionManager(DataSource dataSource){
return new DataSourceTransactionManager(dataSource);
}
@Bean
public DataSource dataSource() throws PropertyVetoException {
ComboPooledDataSource dataSource = new ComboPooledDataSource();
dataSource.setUser("root");
dataSource.setPassword("123456");
dataSource.setDriverClass("com.mysql.cj.jdbc.Driver");
dataSource.setJdbcUrl("jdbc:mysql:///test?characterEncoding=utf-8&useSSL=true&serverTimezone=UTC");
return dataSource;
}
@Bean
public JdbcTemplate jdbcTemplate(DataSource dataSource){
return new JdbcTemplate(dataSource);
}
}
@Test
public void testAccountService(){
AnnotationConfigApplicationContext context = new AnnotationConfigApplicationContext(SpringConfig.class);
AccountService accountService = context.getBean(AccountService.class);
Account account = accountService.queryAccountById(1);
account.setMoney(5000d);
boolean flag = accountService.updateAccount(account);
System.out.println("转账是否成功:" + flag);
Account accountForAfter = accountService.queryAccountById(account.getId());
System.out.println(accountForAfter);
}
-------------------------------------------
个性签名:独学而无友,则孤陋而寡闻。做一个灵魂有趣的人!
如果觉得这篇文章对你有小小的帮助的话,记得在右下角点个“推荐”哦,博主在此感谢!
万水千山总是情,打赏一分行不行,所以如果你心情还比较高兴,也是可以扫码打赏博主,哈哈哈(っ•̀ω•́)っ✎⁾⁾!