今天来聊一聊我对spring框架的认识,本篇章中不详细讲解具体的使用方法和实现
一、spring是什么?
spring 是一个java语言下的bean管理的基础框架。
二、spring的常用功能有那些,分别解决了那些问题?
-
IOC
IOC容器帮我们解决了bean对象的管理繁琐问题,例如:创建、对象之间的相互依赖、对象的销毁等相关问题。为了更好的体现spring的便利性,下面来看两段代码对bean对象的操作与管理。
//第一种,自己管理bean对象,实现了两层逻辑dao层和service层,分别需要自行创建对象和设置相应的属性值,当有更多的对象和对象间的相互引用时代码会更难管理和维护; public interface UserDao {User get(Long userId);} public class UserDaoImpl implements UserDao { @Override public User get(Long userId) { if (Objects.equals(1L, userId)) { User user = new User(); user.setUserId(1L); user.setUserName("zhangsan"); return user; } return null; } } public interface UserService {User get(Long userId);} public class UserServiceImpl implements UserService { private UserDao userDao; @Override public User get(Long userId) {return userDao.get(userId);} public UserDao getUserDao() {return userDao;} public void setUserDao(UserDao userDao) {this.userDao = userDao;} } public class Main { public static void main(String[] args) { UserDao userDao = new UserDaoImpl(); UserServiceImpl userService = new UserServiceImpl(); userService.setUserDao(userDao); User user = userService.get(1L); System.out.println(user); userService = null; userDao = null; } }
//第二种使用spring对bean进行管理,相同的代码添加几个简单的注解既可以实现,注意下方带1,2,3的注释行,1,2两个注解的本质都是使用@Component对类进行标注,spring容器启动时对代码进行扫描并检查@Component注解实现对bean Definition信息的生成,在main方法中调用getBean兑现时,spring通过bean Defintion信息创建对象,并根据@Autowired注解进行属性的注入,从而把dao对象填充到service中。 public interface UserDao {User get(Long userId);} @Repository //1 public class UserDaoImpl implements UserDao { @Override public User get(Long userId) { if (Objects.equals(1L, userId)) { User user = new User(); user.setUserId(1L); user.setUserName("zhangsan"); return user; } return null; } } public interface UserService {User get(Long userId);} @Service //2 public class UserServiceImpl implements UserService { private UserDao userDao; @Override public User get(Long userId) {return userDao.get(userId);} public UserDao getUserDao() {return userDao;} @Autowired //3 public void setUserDao(UserDao userDao) {this.userDao = userDao;} } public class SpringMain { public static void main(String[] args) { AnnotationConfigApplicationContext ac = new AnnotationConfigApplicationContext("output01.spring"); UserService userService = ac.getBean(UserService.class); User user = userService.get(1L); System.out.println(user); ac.close(); } }
-
AOP
aop是基于spring的bean管理而扩展出的动态代理功能,spring通过jdk或cglib根据相应的配置生成指定对象的代理对象(子类对象),可以对特定方法的前后增加自定义的业务逻辑,且对原有代码无侵入; 可以帮助我们解决一些通用性的业务逻辑,例如通过aop实现方法的耗时统计日志等等操作;下面我们写一段代码进行简单的演示,打印方法的名称和方法耗时,以上边的userService为例:
//增加一个类LogUitl, 为了体现效果UserServiceImpl get方法中打印一行日志,其他代码不修改, //@Aspec注解标记此类是一个切面类;@Component为了spring扫描当前bean对象;@EnableAspectJAutoProxy为了spring开始aop代理功能 //@Around指定在被拦截的方法前后执行代码 //输出效果,实际生产中为了更方便的排查日志,应该把开始和结束时间打印在一行日志中,本案例为了更方便的展示效果故输出为两行 /* LogUitl: output01.spring.UserServiceImpl.get START: 1676811558765 UserServiceImpl.get do...... LogUitl: output01.spring.UserServiceImpl.get END: 1676811558765 */ @Service public class UserServiceImpl implements UserService { private UserDao userDao; @Override public User get(Long userId) { System.out.println("UserServiceImpl.get do......"); return userDao.get(userId); } public UserDao getUserDao() {return userDao;} @Autowired public void setUserDao(UserDao userDao) {this.userDao = userDao;} } @Aspec @Component @EnableAspectJAutoProxy public class LogUitl { @Around(value = "execution(* output01.spring.UserService.*(..))") public Object around(ProceedingJoinPoint proceedingJoinPoint) throws Throwable { String className = proceedingJoinPoint.getTarget().getClass().getName(); String methodName = proceedingJoinPoint.getSignature().getName(); long startTime = System.currentTimeMillis(); try { System.out.println("LogUitl: " + className + "." + methodName + " START: " + startTime); return proceedingJoinPoint.proceed(); } finally { long endTime = System.currentTimeMillis(); System.out.println("LogUitl: " + className + "." + methodName + " END: " + endTime); } } }
-
事务
事务是spring基于Aop功能的基础上帮我们实现的数据据事务管理功能,可以在系统抛出运行时异常时自动回滚数据库事务,避免手动管理数据库事务的繁琐,spring可以根据实际的配置实现不同的事务传播方法,事务隔离级别;