Spring实战笔记 1

虽然Spring用bean或者JavaBean来表示应用组件,但并不意味着Spring组件必须要遵循JavaBean规范。一个Spring组件可以是任何形式的POJO。


三个主要内容:依赖注入,切面,模板代码

<beans>
	<aop:config>
		<aop:aspect ref="minstrel">
			<aop:pointcut id="embark" expression="execution(* *.embarkOnQuest(...))" />
			<aop:before pointcut-ref="embark" method="singBeforeQuest" />
			<aop:after pointcut-ref="embark" method="singAfterQuest">
		</aop:aspect>
	</aop:config>
</beans>


表达式的语法采用的是AspectJ的切点表达式语言。


public Employee getEmployeeById(long id){
	return jdbcTemplate.queryForObject(
		"select id, firstname, lastname, salary from employee where id=?",
		new RowMapper<Employee>(){
			public Employee mapRow(ResultSet rs, int rowNum) throws SQLException {
				Employee employee = new Employee();
				employee.setId(rs.getLong("id"));
				employee.setFirstName(rs.getString("firstname"));
				employee.setLastName(rs.getString("lastname"));
				employee.setSalary(rs.getBigDecimal("salary"));
				return employee;
			}
		}
	)
}



常用的应用上下文:
AnnotationConfigApplicationContext
AnnotationConfigWebApplicationContext
ClassPathXmlApplicationContext
FileSystemXmlApplicationContext
XmlWebApplicationContext


Bean的生存周期:
实例化 => 填充属性 => BeanNameAware => BeanFactoryAware => ApplicationContextAware
 => BeanPostProcessor的预初始化方法 => InitializingBean的afterPropertiesSet方法 => 调用自定义初始化方法 => 调用BeanPostProcessor的初始化后方法
 => Bean可以使用了
 => 调用DisposableBean的destroy()方法 => 调用自定义销毁方法


 Spring框架的模块分类:
1. Spring核心容器: Beans, Core, Context, Expression, Context support
2. 面向切面编程: AOP, Aspects
3. 数据访问与集成:JDBC, Transaction, ORM, OXM, Messaging, JMS
4. Web与远程调用:Web, Web servlet, Web portlet, WebSocket
5. Instrumentation: Instrument, Instrument Tomcat
6. Test


Spring提供了三种主要的装配机制:
1. 在XML中进行显式配置
2. 在Java中进行显式配置
3. 隐式的bean发现机制和自动装配。


自动发现:
@Configuration
@ComponentScan
public class CDPlayerConfig{
}
按照默认规则,它会以配置类所在的包作为基础包来扫描组件。
@ComponentScan("soundsystem")
@ComponentScan(basePackages={"soundsystem", "video"})
@ComponentScan(basePackageClasses={CDPlayer.class, DVDPlayer.class})



@RunWith(SpringJUnit4ClassRunner.class)
@ContextConfiguration(classes=CDPlayerConfig.class)
public class CDPlayerTest{
	@Test
	public void fn(){
		System.out.println(1);
	}
}




profile bean。
Spring为环境相关的bean所提供的解决方案其实与构建时的方案没有太大的差别。当然,在这个过程中需要根据环境决定该创建哪个bean和不创建哪个bean。不过Spring并不是在构建的时候做出这样的决策,而是等到运行时再来确定。这样的结果就是同一个部署单元(可能会是WAR文件)能够适用于所有的环境,没有必要进行重新构建。
Spring在确定哪个profile处于激活状态时,需要依赖两个独立的属性:spring.profiles.active和spring.profiles.default。
有多种方式来设置这两个属性:
作为DispatcherServlet的初始化参数。
作为Web应用的上下文参数
作为JNDI条目
作为环境变量
作为JVM的系统属性
在集成测试类上,使用@ActiveProfiles注解设置。


Spring定义了多种作用域,可以基于这些作用域创建bean,包括:
1. 单例(Singleton):在整个应用中,只创建bean的一个实例。
2. 原型(Prototype):每次注入或者通过Spring应用上下文获取的时候,都会创建一个新的bean实例。
3. 会话(Session):在Web应用中,为每个会话创建一个bean实例。
4. 请求(Request):在Web应用中,为每个请求创建一个bean实例。


@Component
@Scope(
	value=WebApplicationContext.SCOPE_SESSION,
	proxyMode=ScopedProxyMode.INTERFACES)
public ShoppingCart cart(){ ... }


proxyMode这个属性解决了将会话或请求作用域的bean注入到单例bean中所遇到的问题。


在@Configuration类上可以指定@PropertySource注解来指定属性来源,之后就可以注入Environment来调用它的getProperty方法获取属性性。


Spring切面可以应用5种类型的通知:
1. 前置通知
2. 后置通知
3. 返回通知
4. 异常通知
5. 环绕通知








第10章


在开发应用的持久层的时候,会面临多种选择,我们可以使用JDBC、Hibernate、Java持久化API(JPA)或者其他任意的持久化框架。


为了避免持久化的逻辑分散到应用的各个组件中,最好将数据访问的功能放到一个或多个专注于此项任务的组件中。这样的组件通常称为数据访问对象(DAO)或Repository。
为了避免应用与特定的数据访问策略耦合在一起,编写良好的Repository应该以接口的方式暴露功能。
如果在阅读了上面几段文字之后,你能感受到我倾向于将持久层隐藏在接口之后,那很高兴我的目的达到了。我相信接口是实现松耦合代码的关键,并且应将其用于应用程序的各个层,而不仅仅是持久化层。


Spring提供与平台无关的持久化异常,这意味着我们可以使用Spring抛出一致的异常,而不用关心所选择的持久化方案。
这些异常都继承自DataAccessException,DataAccessException的特殊之处在于它是一个非检查型异常。换句话说,没有必要捕获Spring所抛出的数据访问异常(当然,如果你想捕获的话也是完全可以的)。


配置数据源的三种方式:
1. 通过JDBC驱动程序定义的数据源。
2. 通过JNDI查找的数据源。
3. 连接池的数据源。
对于即将发布到生产环境中的应用程序,我建议使用从连接池获取连接的数据源。如果可能的话,我倾向于通过应用服务器的JNDI来获取数据源。


1.在Spring中,通过JDBC驱动定义数据源是最简单的配置方式。Spring提供了三个这样的数据源类:
DriverManagerDataSource:在每个连接请求时都会返回一个新建的连接
SimpleDriverDataSource:与DriverManagerDataSource的工作方式类似,但是它直接使用JDBC驱动,来解决在特定环境下的类加载问题。
SingleConnectionDataSource:在每个连接请求时都会返回同一个连接。


2.通过JNDI查找数据源。
利用Spring,我们可以像使用Spring bean那样配置JNDI中数据源的引用并将其装配到需要的类中。
<jee:jndi-lookup id="dataSource" jndi-name="/jdbc/SpitterDSxx" resource-ref="true">




3.如果你不能从JNDI中查找数据源,那么下一个选择就是直接在Spring中配置数据源连接池。尽管Spring并没有提供数据源连接池的实现,但是我们有多项可用的方案,包括如下开源的实现:
Apache Commons DBCP
c3p0
BoneCP
<bean id="dataSource" class="org.apache.commons.dbcp.BasicDataSource"
 p:driverClassName="org.h2.Driver"
 p:url="jdbc:h2:tcp://localhost/~/spitter"
 p:username="sa"
 p:password=""
 p:initialSize="5"
 p:maxActive="10" />
@Bean
public BasicDataSource dataSource(){
	BasicDataSource ds = new BasicDataSource();
	ds.setDriverClassName("org.h2.Driver");
	ds.setUrl("jdbc:h2:tcp://localhost/~/spitter");
	ds.setUsername("sa");
	ds.setPassword("");
	ds.setInitialSize(5);
	ds.setMaxActive(10);
	return ds;
}


嵌入式的数据源
<jdbc:embedded-database id="dataSource" type="H2">
	<jdbc:script location="com/habuma/spitter/db/jdbc/schema.sql" />
	<jdbc:script location="com/habuma/spitter/db/jdbc/test-data.sql" />
</jdbc:embedded-database>
@Bean
public DataSource dataSource(){
	return new EmbeddedDatabaseBuilder()
		.setType(EmbeddedDatabaseType.H2)
		.addScript("classpath:schema.sql")
		.addScript("classpath:test-data.sql")
		.build();
}


Connection conn = dataSource.getConnection();
PreparedStatement stmt = conn.prepareStatement(SQL_SELECT_SPITTER);
stmt.setLong(1, id)
ResultSet rs = stmt.executeQuery();



Spring为JDBC提供的模板类:JdbcTemplate和NamedParameterJdbcTemplate。


配置JdbcTemplate bean:
@Bean
public JdbcTemplate jdbcTemplate(DataSource dataSource){
	return new JdbcTemplate(dataSource);
}
使用:
@Repository
public class JdbcSpitterRepository implements SpitterRepository{
	private JdbcOperations jdbcOperations;


	@Inject
	public JdbcSpitterRepository(JdbcOperations jdbcOperations) {
		this.jdbcOperations = jdbcOperations;
	}
}


在这里,JdbcSpitterRepository类上使用了@Repository注解,这表明它将会在组件扫描的时候自动创建。它的构造器上使用了@Inject注解,因此在创建的时候,会自动获得一个JdbcOperations对象。JdbcOperations是一个接口,定义了JdbcTemplate所实现的操作。
public void addSpitter(Spitter spitter){
	jdbcOperations.update(INSERT_SPITTER,
		spitter.getUsername(),
		spitter.getPassword(),
		spitter.getFullName(),
		spitter.getEmail(),
		spitter.isUpdateByEmail());
}
public Spitter findOne(long id) {
	return jdbcOperations.queryForObject(
		SELECT_SPITTER_BY_ID,
		(rs, rowNum) -> {
			return new Spitter(xxx);
		}, id);
}
或用方法引用
public Spitter findOne(long id) {
	return jdbcOperations.queryForObject(SELECT_SPITTER_BY_ID, this::mapSpitter, id);
}
public Spitter mapSpitter(ResultSet rs, int row) throws SQLException{
	xxx
}




Hibernate是在开发者社区很流行的开源持久化框架。它不仅提供了基本的对象关系映射,还提供了ORM工具所应具有的所有复杂功能,比如缓存、延迟加载、预先抓取以及分布式缓存。


使用Hibernate所需的主要接口是org.hibernate.Session。Session接口提供了基本的数据访问功能,如保存、更新、删除以及从数据库加载对象的功能。通过Hibernate的Session接口,应用程序的Repository能够满足所有的持久化需求。
获取Hibernate Session对象的标准方式是借助于Hibernate SessionFactory接口的实现类。除了一些基他的任务,SessionFactory主要负责Hibernate Session的打开、关闭以及管理。
@Bean
public LocalSessionFactoryBean sessionFactory(DataSource ds) {
	LocalSessionFactoryBean sfb = new LocalSessionFactoryBean();
	sfb.setDataSource(ds);
	sfb.setPackagesToScan(new String[]{"com.habuma.spittr.domain"});
	Properties props = new Properties();
	props.setProperty("dialect", "org.hibernate.dialect.H2Dialect");
	sfb.setHibernateProperties(props);
	return sfb;
}




基于JPA的应用程序需要使用EntityManagerFactory的实现类来获取EntityManager实例。JPA定义了两种类型的实体管理器:应用程序管理类型,容器管理类型。
以上的两种实体管理器实现了同一个EntityManager接口。关键的区别不在于EntityManager本身,而是在于EntityManager的创建和管理方式。应用程序管理类型的EntityManager是由EntityManagerFactory创建的,而后者是通过PersistenceProvider的createEntityManagerFactory()方法得到的。与此相对,容器管理类型的EntityManagerFactory是通过PersistenceProvider的createContainerEntityManagerFactory()方法获得的。
这两种实体管理器工厂分别由对应的Spring工厂Bean创建:
LocalEntityManagerFactoryBean生成应用程序管理类型的EntityManagerFactory。
LocalContainerEntityManagerFactoryBean生成容器管理类型的EntityManagerFactory。

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
目标检测(Object Detection)是计算机视觉领域的一个核心问题,其主要任务是找出图像中所有感兴趣的目标(物体),并确定它们的类别和位置。以下是对目标检测的详细阐述: 一、基本概念 目标检测的任务是解决“在哪里?是什么?”的问题,即定位出图像中目标的位置并识别出目标的类别。由于各类物体具有不同的外观、形状和姿态,加上成像时光照、遮挡等因素的干扰,目标检测一直是计算机视觉领域最具挑战性的任务之一。 二、核心问题 目标检测涉及以下几个核心问题: 分类问题:判断图像中的目标属于哪个类别。 定位问题:确定目标在图像中的具体位置。 大小问题:目标可能具有不同的大小。 形状问题:目标可能具有不同的形状。 三、算法分类 基于深度学习的目标检测算法主要分为两大类: Two-stage算法:先进行区域生成(Region Proposal),生成有可能包含待检物体的预选框(Region Proposal),再通过卷积神经网络进行样本分类。常见的Two-stage算法包括R-CNN、Fast R-CNN、Faster R-CNN等。 One-stage算法:不用生成区域提议,直接在网络中提取特征来预测物体分类和位置。常见的One-stage算法包括YOLO系列(YOLOv1、YOLOv2、YOLOv3、YOLOv4、YOLOv5等)、SSD和RetinaNet等。 四、算法原理 以YOLO系列为例,YOLO将目标检测视为回归问题,将输入图像一次性划分为多个区域,直接在输出层预测边界框和类别概率。YOLO采用卷积网络来提取特征,使用全连接层来得到预测值。其网络结构通常包含多个卷积层和全连接层,通过卷积层提取图像特征,通过全连接层输出预测结果。 五、应用领域 目标检测技术已经广泛应用于各个领域,为人们的生活带来了极大的便利。以下是一些主要的应用领域: 安全监控:在商场、银行
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值