Wetts's blog

Stay Hungry, Stay Foolish.

0%

单一职责原则(Single Responsibility Principle,简称SRP)

There should never be more than one reason for a class to change.


单一职责原则的好处:

  • 类的复杂性降低,实现什么职责都有清晰明确的定义;
  • 可读性提高,复杂性降低,那当然可读性提高了;
  • 可维护性提高,可读性提高,那当然更容易维护了;
  • 变更引起的风险降低,变更时必不可少的,如果接口的单一职责做得好,一个接口修改只对相应的实现类有影响,对其他的接口无影响,这对系统的扩展性、维护性都有非常大的帮助。

接口一定要做到单一职责,类的设计尽量做到只有一个原因引起变化。

1. 在/etc/init.d/目录下创建脚本

1
vi /etc/init.d/nginx

2. 更改脚本权限

1
chmod 775 /etc/init.d/nginx

3. 编写脚本内容

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
#!/bin/bash
# nginx Startup script for the Nginx HTTP Server
# it is v.0.0.2 version.
# chkconfig: - 85 15
# description: Nginx is a high-performance web and proxy server.
# It has a lot of features, but it's not for everyone.
# processname: nginx
# pidfile: /var/run/nginx.pid
# config: /usr/local/nginx/conf/nginx.conf
nginxd=/usr/local/webserver/nginx/sbin/nginx
nginx_config=/usr/local/webserver/nginx/conf/nginx.conf
nginx_pid=/usr/local/webserver/nginx/logs/nginx.pid
RETVAL=0
prog="nginx"
# Source function library.
. /etc/rc.d/init.d/functions
# Source networking configuration.
. /etc/sysconfig/network
# Check that networking is up.
[ ${NETWORKING} = "no" ] && exit 0
[ -x $nginxd ] || exit 0
# Start nginx daemons functions.
start() {
if [ -e $nginx_pid ];then
echo "nginx already running...."
exit 1
fi
echo -n $"Starting $prog: "
daemon $nginxd -c ${nginx_config}
RETVAL=$?
echo
[ $RETVAL = 0 ] && touch /var/lock/subsys/nginx
return $RETVAL
}
# Stop nginx daemons functions.
stop() {
echo -n $"Stopping $prog: "
killproc $nginxd
RETVAL=$?
echo
[ $RETVAL = 0 ] && rm -f /var/lock/subsys/nginx /usr/local/webserver/nginx/logs/nginx.pid
}

reload() {
echo -n $"Reloading $prog: "
#kill -HUP `cat ${nginx_pid}`
killproc $nginxd -HUP
RETVAL=$?
echo
}
# See how we were called.
case "$1" in
start)
start
;;
stop)
stop
;;
reload)
reload
;;
restart)
stop
start
;;
status)
status $prog
RETVAL=$?
;;
*)
echo $"Usage: $prog {start|stop|restart|reload|status|help}"
exit 1
esac
exit $RETVAL

4. 设置开机启动

1
chkconfig nginx on

1. 将mysql安装目录下 support-files目录下的mysql.server文件拷贝到/etc/init.d/目录下并改名为mysqld,并更改权限

1
chmod 775 /etc/init.d/mysqld

2. 设置开机启动

1
chkconfig mysqld on

今天在使用两个BigDecimal类型的数字做除法运算时,出现了一个如下的异常信息:

1
java.lang.ArithmeticException: Non-terminating decimal expansion; no exact representable decimal result

上网查了一下这个异常的,找到了原因所在:通过BigDecimal的divide方法进行除法时当不整除,出现无限循环小数时,就会抛异常:java.lang.ArithmeticException: Non-terminating decimal expansion; no exact representable decimal result.

解决的办法就是给divide方法设置精确的小数点,如:divide(xxxxx,2)。

JDK动态代理创建的代理对象,在JDK1.3下,性能差强人意。虽然在高版本的JDK中,动态代理对象的性能得到了很大的提高,但是有研究表明,CGLib所创建的动态代理对象的性能依旧比JDK的所创建的代理对象的性能搞不少(大概10倍)。但CGLib在创建代理对象时所花费的时间却比JDK动态代理多(大概8倍),所以对于singleton的代理对象或者具有实例池的代理,因为无须频繁创建代理对象,所以比较适合用CGLib动态代理技术,反之适合用JDK动态代理技术。值得一提的是,由于CGLib采用动态创建子类的方式生成代理对象,所以不能对目标类中的final,private等方法进行代理。

注解

  • @Component
  • @Repository:用于对DAO实现类进行标注
  • @Service:用于对Service实现类进行标注
  • @Controller:用于对Controller实现类进行标注
  • @Scope:指定Bean的作用范围
  • @PostConstruct:相当于init-method,可以在一个Bean中定义多个
  • @PreDestroy:相当于destroy-method,可以在一个Bean中定义多个
  • @Autowired:按类型注入
  • @Resource:按名称注入
  • @Inject:跟@Autowired类似,只不过没有required属性
  • @Lazy:设置懒加载

扫描注解

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
<context:component-scan base-package="" />
指定路径,扫描该基路径里所有类的注解信息。

<context:component-scan base-package="com.wetts" resource-pattern="anno/*.class" />
扫描特定的类而非基路径下的所有类。
默认情况下resource-pattern属性的值为“**/*.class”,即基类包里的所有类。

<context:component-scan base-package="" />
<context:include-filter type="regex" expression="" />
<context:exclude-filter type="aspecj" expression="" />
</context:component-scan>
<context:include-filter>表示要包含的目标类,<context:exclude-filter>表示要排除在外的目标类。
<context:component-scan>下可以拥有若干个<context:include-filter>和<context:exclude-filter>元素。
这两个过滤元素均支持多种类型的过滤表达式:
annotation
示例:com.wetts.XxxAnnotation
所有标注了XxxAnnotation的类。该类型采用目标类是否标注了某个注解进行过滤。
assignable
示例:com.wetts.XxxService
所有继承或扩展了XxxService的类。该类型采用目标类是否继承或扩展某个特定类进行过滤。
aspectj
示例:com.wetts..*Service+
所有类名以Service结束的类及继承或扩展它们的类。
regex
示例:com\.wetts\.anno\..*
所有com.wetts.anno类包下的类。该类型采用正则表达式根据目标类的类名进行过滤。
custom
示例:com.wetts.XxxTypeFilter
采用XxxTypeFile通过代码的方式根据过滤规则。该类必须实现org.springframework.core.type.TypeFilter接口。

@Autowired@Resource

@Autowired

默认按类型匹配的方式,在容器中查找匹配的Bean,当有且仅有一个匹配的Bean时,Spring将其注入到@Autowired标注的变量。

可以对类成员变量及方法的入参进行标注。

1
2
@Autowired
public void init(@Qualifier("userDao")UserDao userDao, LogDao logDao) {}

如果容器中没有一个和标注变量类型匹配的Bean,Spring容器启动时将报NoSuchBeanDefinitionException异常。如果希望Spring即使找不到匹配的Bean完成注入也不要抛出异常,那么可以使用@Autowired(required=false)进行标注。默认为true。

如果容器中有一个以上匹配的Bean时,则可以通过@Qualifier注解限定Bean的名称。

如果对类中集合的变量或方法入参进行@Autowired标注,Spring会将容器中类型匹配的所有Bean都自动注入进来。

1
2
@Autowired(required=false)
private List<Plugin> plugins;

@Resource

要求提供一个Bean名称的属性,如果属性为空,则自动采用标注处的变量名或方法名作为Bean的名称。

直接通过Configuration类启动Spring容器

Spring提供了一个AnnotationConfigApplicationContext类,它能够直接通过标注@Configuration的Java类启动Spring容器

1
ApplicationContext ctx = new AnnotationConfigApplicationContext(AppConf.class);

AnnotationConfigApplicationContext还支持通过编码的方式加载多个@Configuration配置类

1
2
3
4
AnnotationConfigApplicationContext ctx = new AnnotationConfigApplicationContext();
ctx.register(DaoConfig.class);
ctx.register(ServiceConfig.class);
ctx.refresh(); // 刷新容器以应用这些注册的配置类

你也可以通过代码一个一个注册配置类,也可以通过@Import将多个配置类组装到一个配置类中,这样仅需要注册这个组装好的配置类就可以启动容器了

1
2
@Configuration
@Import(DaoConfig.class)

通过XML配置文件引用@Configuration的配置

标注了@Configuration的配置类本身相当于一个标注了@Component的类一样也是一个Bean,它可以被Spring的<context:component-scan>扫描到。

通过Configuration配置类引用XML配置信息

在@Configuration配置类中可通过@ImportResource引入XML配置文件,在配置类中即可直接通过@Autowired引入XML配置文件中定义的Bean

1
2
@Configuration
@ImportResource("classpath:com/wetts/applicationContext.xml")

  • @Configuration
  • @Bean
  • @Import:将多个配置类组装到一个配置类中
  • @ImportResource:在@Configuration配置类中引入XML配置文件
  • @Lazy:设置懒加载

标注了@Configuration,说明这个类可用于为Spring提供Bean的定义信息。类的方法处可以标注@Bean注解,Bean的类型由方法返回值类型决定,名称默认和方法名相同,也可通过入参显示指定Bean名称,如@Bean(name=”userDao”)。


如果Bean在多个@Configuration配置类中定义,如何引用不同配置类中定义的Bean呢?

由于@Configuration注解类本身已经标注了@Component注解,所以任何标注了@Configuration的类,本身也相当于注解了@Component,即它们可以像普通的Bean一样被注入到其他Bean中。


在@Bean处,可以标注@Scope注解以控制Bean的作用范围。


由于Spring容器会自动对@Configuration的类进行“改造”,以植入Spring容器对Bean的管理逻辑,所以使用基于Java类的配置必须保证将Spring AOP类包和CGLIB类包加载到类路径下。

继承

如果多个<bean>存在相同的配置信息,Spring允许我们定义一个父<bean>,子<bean>将自动继承父<bean>的配置信息。

1
2
<bean id="parent" class="" abstract="true"></bean>
<bean id="child" parent="parent"></bean>

依赖

1
2
<bean id="manager" class="" depends-on="init" />
<bean id="init" class="" />

得到manager之前,先实例化init

引用

一个要引用另一个的id属性值

1
2
3
4
5
6
<bean id="car" class="" />
<bean id="boss" class">
<property name="carID">
<idref bean="car" />
</property>
</bean>

通过引用另一个的名字