-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy pathspringnotes
249 lines (202 loc) · 12.1 KB
/
springnotes
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
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
Core Spring:
Dependency injection
Aspect oriented programming(AOP)
Spring container
Bean lifecycle
Why spring?
Dependency injection
Goals:
Loose coupling
Coding to interfaces
Makes code easy to understand, easy to test, easy to maintain
Takes care of Corss cutting concerns
Works with POJOS-classes are kept simple
boiler plate reduction throgh aspects and templates-
Spring creates a container which is created from a configuration file. When application is loaded at that time the beans are loaded and kept in a container. We can keep some beans outside the container but we wil have to manage the life cycle(instantiation, destruction). Container manages on behalf of us. Container acts liek factory for beans
Container :
BeanFactory (I)
ApplciationContext(I)
derived from Beanfactroy
Enhances functionality of BeanFactory
Usually used instead of beanFactory
ApplicationContext(I) is container implementation
Setter Injection:
Whenever appn is loaded , employee bean is created in container. Then container will call setter methods. For property to be set one must have setter method in class. This feature is SETTER INJECTION. For setter injection "property" tag is needed. Bean is initialised after creation in container(different than construtor injection)
Constructor injection:
Similar to setter injection but here "constructor-arg" tag is used along with name and value. Here, no need to have setter method, as bean is created alling with passed arguments.
Refernce other beans:
use "ref" attribute of the constriuctor-arg or property tag instad of value tag.
Call back methods:
Interfaces - InitializingBean(I) afterPropertiesSet(), DisposableBean(I) distroy()
If we dont want to use the interfaces then specify init-method and destroy-method attribues at individual bean level.
If all the beans have same attributes then specify in <beans> tag with default-init-method, default-detroy-method attribues. But in this case all the bean definitions/implementations should have these mehods.
If both approaches used togther then the interface methods execute firt than their manula counterparts.
Bean scope:
"scope" attribute of bean tesll sabout the scope of the bean. If not given by default its "singleton" i.e.e only one instance is created and that too at the time of the container creation. But if multiple instances are required then "prototype" scope is used. in this scope every time the constructor is called new bean is provided. It is not instantiated at the time of container creation but at the tim of constructor call. Other scopes are: request(web request), session(web session), globalSession(portal application). Example of prototype is the ticketing system when we will need different ticket each time.
Inner bean and alias:
Inner bean is used when we do not want a bean to be used by other classses.It can be achieved by adding the bena to a property which describes the iner bean.
Alias is used as alter to id of the beam. <alias alias="xyz"> tag is used for this.
Wire == inject
Wiring collections:
list, set(no duplicates), map(any => any), props(string => string).
We can ise list and set interchangably. But need to think of the duplicate elements.</list></set>
<list>
<ref bean="address1">
<ref bean="address2">
</list>
<bean is="" class=""></bean>
<llst> : <value>(list of basic datatypes), <ref>(no primitive types), <bean>, <null>
<set> : <value>, <ref>, <bean>, <null>
<map>: <entry>
<key><value><key-ref><value-ref><bean>
<key>
<entry key ="" value-ref="">
<entry key ="" value-ref="">
</key>
<prop>:<prop>
<props>
<prop key ="poona">poona</prop>
<prop key ="mumbai">mumbai</prop>
</props>
Data types of collection elements:
by default every elemnt in collection is treated as string
datatype can be specified by setting type attribute of <value> tag or value-type attribute of collection tag.
Merging collections:
<bean id ="child" parent="parent">
<property name="same as parent">
<props merge="true">
<prop key="sales">mail1</prop>
<prop key="same as in parent colletion">mail2</prop> * overwrites parent collection value.
</props>
</property>
</bean>
Specifying concrete class for collection
Problem: we can not specify the TreeSet or some other specific implementation with the above approach.
Soulution: user class SetFactoryBean, similarly use ListFactoryBean
<bean class="org......SetFactoryBean">
<property name ="targetSetClass">
<value> java.util.TreeSet</value>
</property>
<property name ="sourceSet">
<set>
<value> 5 </value>
<value> 10 </value>
</set>
</property>
</bean>
Solution2: Using util name spaces
<util:set set-class = "java.util.TreeSet">
<value>5</value>
<value>10</value>
<util:set>
Stabalone collection:
if some one wants to shar a collection between two beans then create a bean with SetFactoryBean and set the property as "sourceSet". In the bean to use rever the id of the stand alone collection bean.
Same can be achieved with util name spaces
Autowiring:
by default its OFF
byName
<bean id="" class="" autowire="byName">
Property name in POJO and ID name of a bean should be same for autowiring to happen
byType
<bean id="" class="" autowire="byType">
Type of the property in the POJO and the config file bean(one of the) should match
Here conflict can ccur if multiple beans with same type are present. below can be used in NA beans
<bean id="" class="" autowire-candidate="false">
constructor:
<bean id="" class="" autowire="constructor">
here if the constructor is presnt then it will be used to initialize the member variabe. Other initializations will be doone by setterInjections.
We can verrite autowire behavior
Autowiring can be set at the beans level as default-autowire="byType"
Autowiring using annotations: Spring 3
Gives fine control as if autowiring is sto be done on specific property vs all the properties in a bean
@Autowired <- be added above the declaration, any method which uses this member type as parameter
<context:annotation-config></context:annotation-config>
Autowired by default is autowired byType
This lead to 2 situations:1) no matching beans 2) multiple matching beans
Situation1:
@Autowired(required=false) <- in this case the dependency is not injected and null is assigned as value.
Situation 2:
1) make member name same as one of the property name
2) Use qualifier
@Autowired
@Qualifier("address2)
private Address address;
config file:
<bean>
<qualifier value = "address2"></qualifier>
Autodiscovery:
Spring itself figures out the all beans in application
gets rid of beans from configuration
@Autowired
private Address address;
<context:component-scan base-package="com.psl.bean></context:component-scan> <- scans throght the entire package. aslo gets rid of <context:annotation-config></context:annotation-config>
Annotate the classes as @Component which we need to identify as beans
Some other annotations: @Component,@controller,@Service,@Repository
Autodiscovery makes config file as small and compact as possible.
JSR 250
Annotations discussed above are specific to spring.
If we want to use standard annotations then go with JSR258 or JSR 330
E.g. @Autowired Spring = @Resource 250 = @Inject 330
@Resource(name="address2")
Aware Interfaces
ApplicationContextAware(I)
Class needs to implememnt the interface and method setApplicationContext(). When bean is created, interface is checked. If implemented then the method is called and bean is ready wit proper context. Its needed when the context needs to be used in other parts of the application like MVC application. If one wants to mek context available in certain POJO, then implement the interface.
BeanNameAware
Wht is the id of the bean which refers the POJO? POJO implements BeanNameAware and setBeanName() method. At the time of bean initialization the method is called and bean name is associated with POJO.
BeanPostProcessor(I)
Used when common logic logic is to be executed for all the beans in config file.
2 methods: Object postProcessAfterInitialization(Object bean, String beanName) throws beanException,postProcessBeforeInitialization(Object bean, String beanName). Should return the bean.
Implement the interface. Include a bean with class implementing the interface. Config processor will detect that the BeanPostProcessor() is implemented by the class and hence apply before and after methods for each bean initialization. Child beans are initialized before parent.
InitializingBeanInterface can be used when we have specific logic for a bean but if we have common logic then this is the choice.
BeanFactoryPostProcessor(I)
Same philosophy as BeanPostProcessor. Just that its at factory level instead of bean level. One method to implement
void postProcessBeanFactory(ConfigurableListableBeanFactory factory)
Bean life cycle:
Initialization and setting the dependencies(till |||);
Instantiate -> populate properties -> BeanNameAware's setBeanName() -> BeanFactoryAware's setBeanFactory() -> ApplicationContextAware's setApplicationContext() ||| preinitialization BeanPostProcessors (global to config/container) -> InitializingBean's afterPropertiesSet() (specific to bean) -> call custom inint-Method() (speific to bean) -> Postinitilization BeanPostProcessors (global to config/container)
Bean is ready to use
Container is shut down
DisposableBeans distroy() -> custom methods destroy() method
Internationalization:
MessageSource(I)-> getMessage() Method
ResourceBundleMessageSource implements MessageSource
ApplicationContext implements MessageSource
Step1:
<bean id ="messagesource" class = "org...ResourceBundleMesageSource">
<property name="basenames">
<list>
<value> messages </value> # if only one property file. For multiple add multiple values
</list>
</property>
</bean>
Step2:
create properties file.
key=Parameter:(0) Parameter:(1)
step3:
context.getMessage("key of the message",parameter to message,"message in case of absense", null);
Approach 2:
have MessageSource member in POJO
@Autowired #by type automatically. matches with parent of ResourceBundleMesageSource in config bean
private MessageSource messageSource;
messageSource.getMessage("key of the message",new Object[]{12,35},"message in case of absense", <locale>);
Multiple Config files:
in large project multiple config files are possible oen for connection, one for common, one for moduleA.
Include all configs in single config by importing then in <beans> with below <import resource="common/Spring-Common.xml">
<import resource="connection/Spring-Connections.xml"> <import resource="moduleA/Spring-ModuleA.xml">
here assumption is that all config files are under project classpath
Spring with database access:
Expensive to write long code to fire single query.
redundant code, maintainance overhead, JDBC is critical to be correct once. Resource intensive. Sinlg exception i.e. SQLException. No way to recover from exception as these are checked exception. 1. Redundant 2. Exceptions are checked.
*hibernate,jdbc,toplink,Jdo are called as enterprise resources
To overcome above limitations Spring provide JDBC template(if using JDBC). For hibernate, hibernate template.
JDBC template takes care of the fixed part(from the JDBC code) like connection, driver loading, closing connections and cleanup. Other variable part needs to be taken care of by developer(execute, return data).
Exception: exception are handled by template and are rethrown as unchecked exception.
Set datasource: JCBC, JNDI , Connection pooling
JDBC: (for smaller applications, for large applications use connection pooling)
DriverManagerDataSource
SingleConectionDataSource
JdbcDaoSupport:(for hibernate HibernateDaoSupport)
Application class will extends the JdbcDaoSupport class.
Choice between Template class and DaoSupport class.
If a application class is alredy extendng a class then due to javas limitaion of single inheritance at a time, we need to user Template class.
mapRow() <- call back method. gets one row at a time from ResultSet