spring框架中所用到的组件
核心:
-IoC:控制反转,降低项目中各种对象(bean)的耦合程度,,是一种OOP的思想,通过依赖注入(DI)实现,而DI的关键是IoC container,其本质是一个工厂
-AOP:面向切面编程,对OOP的一种补充
数据访问:
-transactions:数据处理
-spring MyBatis:
web servlet:
-spring MVC
集成:
-Email,scheduling(定时任务),AMQP(消息队列),security
IoC container:需要两份数据,其一是需要管理的bean,其二是对于bean之间关系的描述。因此在容器里面bean之间并不会直接产生关联,而是通过配置文件里的描述进行关联,降低了耦合度。
在spring运行的时候底层会自动启动IoC容器,并扫描配置类(带有@SpringBootApplication注解)所在的包以及子包中带有特定注解的bean。
能被容器扫描的注解:
@Component:通用
@Controller:处理请求组件
@Service:业务组件
@Repoitory:数据库访问
作业1:定义数据访问组件AlphaDao、业务组件AlphaService、控制器AlphaController,并通过注解的方式将它们委托给Spring容器。
对于数据访问组件AlphaDao:在配置类所在包(com.lyt.community)下建立业务对应的包DAO,在DAO包里建立相应的接口AlphaDao,同时在DAO包里新建实现类AlphaDAOHibernateImpl
@Repository("alphaH") //数据访问类bean的注解,括号内为自定义的bean名,首字母小写
@Primary //当多个方法实现同一个接口时优先使用该方法
public class AlphaDAOHibernateImpl implements AlphaDAO{ #implements AlphaDAO表示实现AlphaDAO的接口
@Override
public String select(){
return "Hibernate";
}
编写测试方法
@Test
public void testApplicationContext(){
System.out.println(applicationContext);
AlphaDAO alphaDAO = applicationContext.getBean(AlphaDAO.class); //按照接口类型获取bean
System.out.println(alphaDAO.select());
alphaDAO = applicationContext.getBean(("alphaH"), AlphaDAO.class); //按照bean名称获取bean,当一个接口有多个实现方法时使用
System.out.println(alphaDAO.select());
}
对于业务组件AlphaService:在配置类所在包(com.lyt.community)下建立业务对应的包service,在包里建立类AlphaService
@Service //业务类bean
//@Scope("prototype") //由容器管理的对象默认是启动时实例化,而加上该注解表示在getbean时实例化
public class AlphaService {
@Autowired
private AlphaDAO alphaDAO;
public AlphaService(){ //对象实例化
System.out.println("AlphaService Instancing");
}
@PostConstruct //构造对象之后立即调用该方法
public void init(){
System.out.println("AlphaService Initializing");
}
@PreDestroy //销毁对象之前调用该方法
public void destory(){
System.out.println("destorying");
}
public String find(){
return alphaDAO.select();
}
}
编写测试方法
@Test
public void testBeanManagement(){
AlphaService alphaService = applicationContext.getBean(AlphaService.class);
System.out.println(alphaService);
System.out.println(alphaService.find());
alphaService = applicationContext.getBean(AlphaService.class);
System.out.println(alphaService);
}
获取了两次对象,但是打印出来都是一样的,说明通过容器管理的bean只被实例化一次,除非在类上加注解@Scope("prototype")
对于业务组件AlphaController:在配置类所在包(com.lyt.community)下建立业务对应的包controller,在包里建立类AlphaController
@Controller //处理请求,一般流程为controller处理浏览器的请求->调用service业务组件->调用DAO访问数据库
@RequestMapping("/alpha")
public class AlphaController {
@Autowired //将AlphaService注入给AlphaController以便调用
private AlphaService alphaService;
@RequestMapping("/hello")
@ResponseBody
public String sayHello(){
return "Hello Spring Boot.";
}
@RequestMapping("/data")
@ResponseBody
public String getData(){ //调用alphaService实现模拟数据查询请求
return alphaService.find();
}
}
问题1:如何使容器能够扫描从外部导入的jar包
答:在项目包下新建一个config包用于存放今后所有的配置文件,在config下新建一个配置类AlphaConfig
@Configuration //表明该类是一个配置类
public class AlphaConfig {
@Bean //定义第三方的bean,bean的名字即是方法的名字,表明该方法返回的对象将被装入容器中
public SimpleDateFormat simpleDateFormat() {
return new SimpleDateFormat(("yyyy-MM-dd HH:mm:ss"));
}
}
编写测试方法
@Test
public void testBeanConfig(){
SimpleDateFormat simpleDateFormat = applicationContext.getBean(SimpleDateFormat.class);
System.out.println(simpleDateFormat.format(new Date()));
}
问题2:使用IoC容器的方法
方法①:使用容器applicationContext.getbean()主动获取bean,
方法②:依赖注入,在成员变量之前加上@Autowired注解将实例化的对象注入到当前的bean,如果根据名称获取bean需要再加@Qualifier("****")